SQLi-labs学习sql注入(五)
文章详细描述了通过在Windows 7环境下使用phpstudy2018部署的sqli-labs进行SQL注入攻击的测试过程。作者在测试中遇到了多种问题,并通过查阅资料和实际操作找到了解决方案。文章还介绍了如何利用burpsuite抓包工具来修改请求头中的user-agent字段进行注入攻击,并详细说明了注入过程中遇到的各种情况及解决方法。 2025-8-5 15:31:35 Author: www.freebuf.com(查看原文) 阅读量:3 收藏

freeBuf

主站

分类

云安全 AI安全 开发安全 终端安全 数据安全 Web安全 基础安全 企业安全 关基安全 移动安全 系统安全 其他安全

特色

热点 工具 漏洞 人物志 活动 安全招聘 攻防演练 政策法规

官方公众号企业安全新浪微博

FreeBuf.COM网络安全行业门户,每日发布专业的安全资讯、技术剖析。

FreeBuf+小程序

FreeBuf+小程序

环境:windows 7 里通过phpstudy2018部署的sqli-labs。

这一关通过不断的尝试,使用单引号、比引号和小括号来尝试,配合布尔盲注,最终确定注入点为 1")。详细过程就不再叙述了。但是需要补充说明一下我在测试过程中遇到的问题。就单独拿username这个字段来说明吧。
1、正常来说,在username字段里输入1") or 1=1#即可。但是我一开始使用的是火狐渗透版本,是在hacker bar里输入的这一串字符,发现怎么也达不到想要的效果,页面没有什么反应,后来查了资料后发现问题在于在hacker bar里提交属于工作,而在页面的username里提交数据,是属于表单提交,两种提交方式对于处理特殊字符+,#等时,效果是不一样的。
2、后来查到了post请求中的字段Content-Type: application/x-www-form-urlencoded,它是 HTTP 协议中用于定义 POST 请求数据格式的一种标准类型,主要用于表单数据的提交。

它的核心特点是:

  • 数据以键值对(key=value)的形式组织,不同键值对之间用 & 分隔(例如 username=test&password=123)
  • 特殊字符会被 URL 编码(例如空格会变成 + 或 %20,# 会变成 %23 等)
  • 服务器收到后会自动解析这种格式,将数据转换为键值对结构供后端程序使用

在网页表单中,这是默认的提交方式(当表单的 enctype 属性未指定时,默认就是这种类型)。
3、后来的测试中,直接写uname=1") or 1=1 #&passwd=1&submit=Submit,页面又提示登录成功了,使用brupsuite抓包发现,也没有对工具里输入的这个字符长串进行编码,也是原样发送的。但是使用页面的表单提交时确实是会被编码的。

所以......也不清楚问题在哪里。以后post请求如果在hackbar里测试不行的话,建议还是要先在页面提供的表单里测试吧。。。

用户名处输入的都没有实际作用,当输入正确的用户名后,会返回SUCCESSFULLY UPDATED YOUR PASSWORD,所以注入点应该在密码处。
这时,可以先使用1'进行测试,结果发现页面会有报错:
image.png
看到有报错就好说了,可以使用报错注入试试,这时就想起updatexml了。hacker bar里

uname=admin&passwd=1' and updatexml(1,concat(0x7e,database(),0x7e),1)# //库名
uname=admin&passwd=1' and updatexml(1,concat(0x7e,(select group_concat(table_name) from information_schema.tables where table_schema='security'),0x7e),1)# //表名
uname=admin&passwd=1' and updatexml(1,concat(0x7e,(select group_concat(column_name) from information_schema.columns where table_schema='security' and table_name='users'),0x7e),1)# //字段~~

这一关是利用了post请求中的user-agent字段,之所以记录这个字段,是为了记录访问信息。原php语句如下:

$insert="INSERT INTO security.uagents(uagent, ip_address, username) VALUES ('$uagent', '$IP', $uname)";
这里解读一下,在上面的语句中库名、表名、字段名等加上反引号是一种防御性写法,属于mysql的特性。例如,order本身是mysql的关键字,但是如果有一个表也叫order,这时给它加上了反引号后,mysql就不会把它当作关键字了,而是表名了。
其中$uagent就是通过超全局变量_SERVER获取的POST请求中的user-agent字段。
在这关里,就需要用到burpsuite来抓包,抓到请求包后对数据库中的User-Agent修改。
当输入完正确的账号密码后,页面提示如下:
image.png
打开burpsuite后,再次输入正确的账号密码,回车后就得到了该请求包。将抓到的合法的包发送到Repeater模块,将user-agent字段设置为一个单引号'发现语句有报错,判断为单引号闭合:
image.png
将user-agent修改为两个单引号,发现不再报错。这时可以猜测两个单引号刚好完成了闭合,这时我们就可以在两个单引号之间来使用报错注入了。
我在写报错注入时,最开始我是直接把user-agent的值修改为了updatexml(1,concat(0x7e,database(),0x7e),1)发现并没有带出数据库名。
原因解释如下:
我输入的updatexml这一长串会被赋值给sql语句里的$uagent变量,问题就在于这个变量两边还有单引号。原始sql语句($insert的值)属于php字符串,php只会把$uagent变量进行替换,但是不会去除这个变量名两边的单引号。替换后的语句里,实际是'updatexml(1,concat(0x7e,database(),0x7e),1)',是他被实际传递给了mysql去执行,而在mysql里,用单引号包括的就是普通字符串,因此得出结论,updatexml语句未被mysql当作函数执行。
解决方案:使用单引号闭合,输入的语句修改成:
' and updatexml(1,concat(0x7e,database(),0x7e),1) and '1'='1 //获得数据库名

这一章节就写这么多吧。

免责声明

1.一般免责声明:本文所提供的技术信息仅供参考,不构成任何专业建议。读者应根据自身情况谨慎使用且应遵守《中华人民共和国网络安全法》,作者及发布平台不对因使用本文信息而导致的任何直接或间接责任或损失负责。

2. 适用性声明:文中技术内容可能不适用于所有情况或系统,在实际应用前请充分测试和评估。若因使用不当造成的任何问题,相关方不承担责任。

3. 更新声明:技术发展迅速,文章内容可能存在滞后性。读者需自行判断信息的时效性,因依据过时内容产生的后果,作者及发布平台不承担责任。

本文为 独立观点,未经授权禁止转载。
如需授权、对文章有疑问或需删除稿件,请联系 FreeBuf 客服小蜜蜂(微信:freebee1024)


文章来源: https://www.freebuf.com/articles/web/443109.html
如有侵权请联系:admin#unsafe.sh