SQL注入原理
SQL inject其目标站点没有对用户在web表单提交或输入查询字符串进行严格的过滤与验证导正拼接的sql语句被带入到数据库执行从而获取数据库信息以及接管权限的web攻击漏洞
#原理
web应用程序没有对用户输入的内容做严格过滤,导致用户输入了恶意的sql语句传递到后端,后端程序拼接sql语句带入到数据库中查询产生sql注入漏洞
sql注入条件
sql注入漏洞的产生需要满足以下两个条件:
1.参数是用户可控的,也就是前端传入后端的参数的内容是用户可以控制的
2.参数被带入数据库进行查询,也就是传入的参数被拼接到sql语句中被带入到数据库进行查询
sql注入危害
1.数据库信息泄露;泄露数据库中存放的数据,用户隐私等
2.获取webshell;当权限为root且知道绝对路径时,可以直接写入一句话木马到服务器.
3.网站篡改:注入出后台管理员,登陆后台发布恶心数据.篡改后台数据等
4.获取系统权限:当权限足够高时,可以获取系统主机的权限
5.万能密码:利用特定的payload登陆后台或其他页面
6.文件读取:读取敏感文件
sql注入类型
按照数据库类型分类:
access,myssql,mysql,oracle,DB2
按照提交方式与提交位置:
#提交方式 GET,POST,HTTP头部注入
按照注入点类型
数字型 字符型 搜索型
按照执行效果分类
联合注入,报错注入,布尔盲注,时间盲注,宽字节注入,堆叠注入,二次注入,http/xff头部注入
按照注入点类型:sql注入的类型,在于传递到数据库中的变量的数据类型
1.数字型
大概是:http://www.xxx.com/news.php?id=1 这种形式,其中注入点为id(类型为数字型), 所以 叫数字型注入点。
sql语句原型:select * from 表名 where id=$id;
2.字符型
大概是: http://www.xxx.com/news.php?name=content 这种形式,其注入点name(类型为字符型)
所以叫做字符型注入点。
sql语句原型:select * from 表名 where name ="admin" union select 1,1;
3.搜索型
一般网站为了方便用户寻找网站中得资源,会为提供用户搜索功能。
SQL语句原型:select * from users where content like '%$content%' 使用like/%通配符匹配数据
按照注入方式分类
1.union联合注入
union有一个十分严格得约束条件,因为是联合查询,必须保证左右两边查询结果字段数量必须相同。
2.报错注入
即页面会返回报错/错误信息,那么我们就可以使用报错函数进行注入操作
3.布尔盲注
即页面没有数据回显、也没有报错。只返回两种情况:异常(True)/正常(false),我们可以通过返回页面结果 进行注入。
4.时间盲注
即不能根据页面返回内容判断任何信息,也无报错。这时我们可以使用时间延迟语句是否执行(即页面返回时间 是否增加)来判断;
5.宽字节注入
程序员为了防止sql注入,对用户输入的特殊字符(\ ' " )等进行处理,在特殊字符前加上斜杠 进行转义这样被处理后得SQL语句中得特殊字符就失去了本身得作用,仅仅是变量内容而已。 换句话数:这些特殊字符无法发挥原本得作用,变成了普通得字符串。
6.堆叠注入
使用(mysqli_multi_query)函数,同时执行多条sql语句时注入
7.
sql注入判断
注入判断顺序:判断注入类型-->判断闭合方式-->判断是否存在注入-->注入攻击
sql注入流程
1.判断sql注入漏洞
2.判断字段数
3.确定回显点
4.查询数据库相关信息
5.查询数据库下的表名
6.查询表下的字段名
7.查询字段下的数据
SQL注入类型实操
数字型注入
1.判断是否存在注入 2.判断字段数量 3.通过union 联合注入判断回显位置
4.查询数据库名称 5.查询数据表 6.查询数据表中字段名 7.获取字段名下数据
字符型注入
区别:前面我们学习的数字型注入,首先我们从源码上对比数字型和字符型到底由上面本质区别
闭合:如果我们还拿数字型的语句进行注入的话,使用之前的注入方式会发现页面没有上面变化,这是因为我们输入的sql被 '' 单引号所包裹称为字符串 从而失去了 and 以及其他语句本身的作业
所以我们需要将我们的语句从单引号中逃逸出去
搜索型注入
原理:一些网站为了方便用户查找网站的资源,都对用户提供了搜索的功能,因为是搜索功能,往往是程序员在编写代码时都忽略了对其变量(参数的)过滤
#功能介绍
like则时一种语句,用于模糊查询,主要是针对字符型字段的.在一个v额字符型字段中检索包含对应字串,从某种意义上将,like可看作时一个精简的正则表达式功能
#语法格式
select * from 表名 where 字段名 like 对应值(字串)
#like支持类型
like主要支持两种通配符,分别时"_"和"%"
"_"代表匹配1个任意字符,常用于充当占位符
"%"代表匹配0个或多个任意字符
1.查看存在搜索行注入的页面源码,发现搜索前端GET方式过滤的name字符按未经过过滤直接拼接到sql语句中执行
2.在搜索的内容后面田间引号尝试闭合报错,在从单引号添加模糊匹配的百分号即 "%" 在进行闭合成功
3.判断字段数并按照如下套路进行注入即可
SQL注入方式实操
union联合注入
union联合注入顾名思义,就是使用联合查询注入的一种方式,时一种高校的注入方式,适用于有会先同时数据库版本时5.0以上的mysql数据库(5.0以后没有内置表)能够快速通过几条注入语句获取数据
使用条件:uinion有一个十分雅阁的约束条件,因为时联合擦汗寻,必须保证字段数一致,即两个查询结果有相同的列数,因此我们后面要对字段数进行判断,且页面有数据回显点
报错注入
报错注入用在数据库的错误信息会回显在网页中的情况,如果联合查询不能使用则首先报错注入;其报错注入利用的时数据库报错信息得到数据库的内容,且还需要构造语句让数据库报错
前提条件:数据库的错误信息(mysqli_error()) 返回在当前页面上,如果使用union失败首选报错注入
常用函数:
extractvalue()
updatexml()
floor()
exp()
linestring()
geometrycollection()
multipoint()
polygon()
multipolygon()
multilinestring()
updatexml()函数
函数的作用就是i改变(查找并替换)xml文档中符合条件的节点的值
语法格式:updatexml(xml_document,XPthstring,new_value)
第一个参数:是字符串string(xml文档对象的名称)
第二个参数:是指定字符串中的一个位置(xpath格式的字符串)
第三个参数:是将要替换成上面,string格式
xpath定位必须是有效的,否则则会发生错误,我们就能利用这个特性爆出我们想要的数据
报错原理
第二个参数xml路径是可操作的地方,xml文档中路径是用/xxx/xxx/xxx/这种格式,如果我们写入其他格式,就会报错,而当报错内容为sql语句的时候,sql条用解析器会自动解析该sql语句,就会造成sql语句的执行,从而触发sql注入
extractvalue()函数
extractvalue()函数的作用是从目标xml中返回包含所查询值得字符串
函数格式:extractvalue(xml_document,xpath_string)
第一个参数:xml_document是string格式,为xml文档对象得名称
第二个参数.xpath_string(xpath格式得字符串),xpath定位必须是有效得,否则会发生错误
报错原理与updatexml一样
布尔盲注
不二忙著,即在页面没有报错细腻些,回显是完成得注入攻击,姿势我们输入得语句让页面呈现出两种状态,相当于true和false,而根据这两种状态可以判断我i们输入得语句是否查询成
布尔注入流程
盲注漏洞源码
$sql="SELECT * FROM users WHERE id='$id' LIMIT 0,1 ";
$result=mysql_query($sql);
$row = mysql_fetch_array($result);
if($row){
echo '<font size="5" color ="#ffff00">'
echo "you are in ......";
echo"<br>"
echo"</font>"}else{
echo '<font size="5" color = "#ffff000">'}
ASCII码表
布尔盲注攻击
1.首先获取闭合与注释方式并判断数据库类型
2.手工判断数据库名得长度与全程....当然也可以借助bp对其ascii吗进行爆破
3.数据库名称判断
4.抓取以下数据包并将其发送到intruder模块下,将截取字符串位置与ascii吗添加攻击向量,并设置攻击为集束炸弹;进入payload标签下设置攻击内容如下并开启爆破攻击
payload1有效载荷给定截取位置,payload2有效载荷给定ascii范围
5.方法二,访问以下路径重新抓包并配置
6.得到了数据库名称之后,接着应该获取数据库下得表得信息
7.获取到数据库下有多少表之后继续进行注入,分别注入出各个表名得长度
8.猜测表名得每个字符得ascii值
9.爆破users字段名
10判断每个字段名称得长度
11.判断每个字段得字符得ascii值
12爆破字段下得内容
13.获取字段内容长度
14.获取第一个字段内容
时间盲注
基于时间得盲注也叫做延时注入 ,数据交互完成以后目标网站没有错误和正确得页面回显,那么我们可以考虑到"绝招" ->延时注入,其利用条件较为苛刻,这种情况我们可利用时间函数来判断数据有没有在目标数据中得到执行,当然也需要构造闭合
使用条件:完全没有变化得页面!
相关函数:sleep() benchmark(a,b) if(a,b,c) ascii() length() substr() limit
时间盲注攻击
1.判断是否存在漏洞
2.判断数据库长度并开始猜测数据库得库名
3.依次获取其表得数量,长度与表得名称
4.判断字段数量长度与字段内容
5.判断username字段名下数据数量
6.判断字段下第一个内容长度
#布尔盲注和时间盲注得区别
1.布尔盲注是进行逻辑判断,适用与注入页面存在两种状态:正常页面/报错页面
2.时间盲注是进行if判断联合sleep函数执行,适用于注入页面指存在一种状态
HTTP头部注入
常见得sql注入一般是通过请求参数或者表单进行注入,而HTTP头部注入式通过HTTP协议头部字段值进行注入,HTTP头注入常存在于以上地址 即:UA头/Cookie/referer/x-forward-for
#产生注入得条件
1.能够对请求头信息进行修改
2.修改得请求头信息能够带入数据库进行查询
3.数据库没有对输入得请求信息做过滤
UA头注入
user-agent:使用服务器能够时候别客户使用得系统,浏览器版本等(很多数据量大得网站中会记录客户使用得操作系统或浏览器版本然后将其存入数据库中)
1.在登陆页面输入信息登陆并抓取数据表,发送到reoeater中在user-agnet后面进行注入测试 使用单引号成功报错确定其sql注入
2.采用报错注入函数获取其当前数据库名称
Cookie注入
cookie:服务端用来记录客户端得状态,有服务端产生,保存在客户端浏览器中,但服务器收集用户得cookie信息时会存在注入.
1.使用dumb进行登陆,并返回cookie信息
2.刷新页面并抓包 在cookie字段测试是否存在sql注入
3.采用报错信息注入函数获取其当前数据库名
referer注入
referer:时http header得一部分,当浏览器向web服务器发送请求得时候,一般会带上referer字段来告诉服务器该从那个页面连接过滤,服务器因此可以获取一些信息用于处理
1.使用dumb进行登陆得时候抓包测试 在referer字段后进行测试报错
2.采用报错注入函数获取其当前数据库名
宽字节注入
宽字节时指多个字节宽度得编码 GB2312,GBK,GB18030,BIGS,Shift_IIS等这些信息都是常说得宽字节,实际上只有两个字节
当某字符得大小为一个字符时,称其字符为窄字符
当某字符得大小为两个字节时,将其字符为宽字节
所有英文默认占一个字节,汉字占两个字节
常见得宽字节编码:GB2312,GBK,GB18030,BIG5.Shift_IIS
1.查看这关的源码,发现传入的ID值经过了 addslashes() 转义函数的处理,所有的单引号双引号字符都会被添加转义字符,接着在带入到数据库查询前设置了 mysql_query("SET NAMES gbk") 即设定字符集为GBK,漏洞就是由于这个设置导致宽字节注入
2.进一步查看该函数,其利用正则匹配将[/,',"]这三个符号都过滤掉了,而我们要绕过这个转义处理,使单引号发挥作用不在被转义,有两个思路:第一种:让斜杠()失去作用 第二种:让斜杠()小时 其中第一个思路就是借鉴程序员得防范思路,对斜杠进行转义使其失去转义单引号得作用,称为普通内容;第二个思路就使宽字节注入
原理:
转义函数对这些编码进行转义时会将转义字符''转为%5c,于是我们在他们前面输入一个单字符编码与他组成一个新 的多字符编码,使得原本的转义字符没有发生作用。
宽字节注入得条件:
1.数据库使用了GBK编码
2.php对用户输入得数据进行了转义操作
转义函数作用:
单引号 ' = \' 双引号 " = \" 反斜杠 \ = \\
url编码
%27 =单引号 %20 = 空格 %23=#号 %5c=\反斜杠 %df %cf
宽字节注入攻击
1.闭合判断是否存在注入(发现'被转义为\')
2.然后使用%df'.此时'会被转义称\' 但是在GBK编码种,\会被单独转义成一个%5c,前面我们加了%df,此时就变成了%df%5c,单引号就可以成功逃逸
宽字节注入修复
1.使用utf-8编码
2.设置参数,character_set_client=binary
3.先调用mysql_set_charset函数设置连接所使用得字符集为GBK,在钓鱼mysql_real_escape_string来过滤用户输入
堆叠注入
堆叠查询也叫堆叠注入,在sql种得分号使用来表示i一个sql语句得结束,实现我们在分号结束后继续构造下一条语句也会一起执行
堆叠注入的使用条件十分有限,其可能受到API或者数据库引擎,又或者权限的限制只有当调用数据库函数 支持执行多条sql语句时才能够使用,利用mysqli_multi_query() 函数就支持多条sql语句同时执行,但实 际情况中,如PHP为了防止sql注入机制,往往使用调用数据库的函数是mysqli_ query()函数,其只能执行 一条语句,分号后面的内容将不会被执行,所以可以说堆叠注入的使用条件十分有限,一旦能够被使用, 将可能对网站造成十分大的威胁。
危害
堆叠注入得危害使很大得,可以任意使用增删改查得语句,例如删除数据库,修改数据库,添加数据库用户
堆叠注入攻击
先查看原代码..在堆叠注入页面中,程序获取 get 参 数的 id ,使用 mysqli 的方式进行数据查询,在执行语句时候使用了 mysqli_multi_query 函数处理 sql 语句, 导致存在堆叠注入。
1.注入判断
2.查询字段
3.判断回显位置
4.查看数据库名称
5.获取表明
6.知道表得列得情况下使用insert into 插入语句进行增加账号,如果使管理表,直接添加管理员账号即可登陆后台
7.以上代码执行后在查看添加得管理员账户
DNSLOG外带注入
在实际得应用场景种,我们一般在进行sql盲注时,为了效率,在load_file()函数未被禁用得情况下,我们可以结合一些dnslog平台,进行外带注入
不管是布尔类型盲注还是时间盲注,都需要发送大量的数据包去判断数据,而这很可能会触发WAF的防 护,因此导致被封IP。所以,如果条件允许,我们可以结合DNSlog来快速的回显数据。MySQL数据库,通 过DNSlog盲注需要用到 load_file() 函数,该函数不仅能加载本地文件,同时也能对URL发起请求。因 此需要使用 load_file() 函数,需要root权限,并且 secure_file_priv 需要为空;
dns原理:
首先需要一个可以配置得域名,比如ceye.io.然后通过代理商设置域名 ceye.io 得nameserver未为字节得服务器a,然后再服务器a上配置好 dns server,这样以来所有ceye.io及其子域名得查询都会到 服务器a上 这时就能够实时监控域名查询请求
外带注入原理
将dnslog平台种得特有字段payload带入目标发起dns请求,通过dns解析将请求后得关键信息组合成新得三级域名带出,再dns服务器得dns日志种显示出来哦
外带注入攻击
1.注入时需要注意,尽量使用hex()函数编码以下,不然可能后无法请求,获取数据后将数据decode(即可)
二次注入
二次注入就是由于数据存储进数据库种时未做好过滤,先提交构造号得特殊字符请求存储进数据库种;然后提交第二次请求时与第一次提交进数据库得字符发生了作用(拼接),形成一条新的sql语句被执行
#漏洞原因
再注册时允许 ' # 这种特殊字符
二次注入攻击
先确定测试的网站是否进行过滤(一般情况下网站都会对输入的参数进行过滤),然后寻找可能会带入恶意 数据 二次使用的地方。
例如用户注册->修改密码 邮箱注册->修改密码 文章添加->文章编辑。找一切存在二次使用的功能点;
二次注入测试 SQL 注入,二次注入多数是字符型注入,所以要注意闭合问题;
万能密码
万能密码本质上也就是sql注入所产生得问题
GETShell姿势
into outfile/into dumpfile
利用into outfile()方法利用得先决条件有三种
web目录具有写入权限,能够使用单引号
知道网站绝对路径(网站目录)-->报错/查看网站得功能点/老旧得资产
secure_file_priv没有具体值(再mysql/my.ini种查看)secure_file_priv=""
GETshell
1.这里使用sql less7 ,经测试判断 其闭合注释为')) --+ 且输入正确得语法就正常显示而错误得语法显示语法错误,页面只存在两种状态即判断为盲注;这里使用延迟曼珠测试 成功
2.使用order by 语句判断字段实例
3.这里假设我们铜火锅一些方法获取到了网站得根目录,尝试写入一句话木马且建议进行十六进制编码
4.访问并连接webshell
sql注入防御
1.函数过滤
2.直接下载相关防范注入文件
3.使用白名单过滤
4.采用PDO连接
5.使用waf拦截