SQL注入笔记
SQL的定义原理
定义:SQL注入即是指web应用程序对用户输入数据的合法性没有判断或过滤不严,攻击者可以在web应用程序中事先定义好的查询语句的结尾上添加额外的SQL语句,在管理员不知情的情况下实现非法操作,以此来实现欺骗数据库服务器执行非授权的任意查询,从而进一步得到相应的数据信息。
原理:SQL注入攻击是通过操作输入来修改SQL语句,用以达到执行代码对WEB服务器进行攻击的方法。简单的说就是在post/getweb表单、输入域名或页面请求的查询字符串中插入SQL命令,最终使web服务器执行恶意命令的过程。可以通过一个例子简单说明SQL注入攻击。假设某网站页面显示时URL为http://www.example.com?test=123,此时URL实际向服务器传递了值为123的变量test,这表明当前页面是对数据库进行动态查询的结果。由此,我们可以在URL中插入恶意的SQL语句并进行执行。另外,在网站开发过程中,开发人员使用动态字符串构造SQL语句,用来创建所需的应用,这种情况下SQL语句在程序的执行过程中被动态的构造使用,可以根据不同的条件产生不同的SQL语句,比如需要根据不同的要求来查询数据库中的字段。这样的开发过程其实为SQL注入攻击留下了很多的可乘之机。
SQL注入的危害
1.窃取数据库敏感信息
2.对数据进行恶意的增删改
3.造成拒绝服务
4.文件系统操作:列目录,读取,写入(一句话木马)等
5.获取服务器权限(执行系统命令)
SQL注入防御
1.参数化查询(不把用户恶意拼接进来的SQL语言执行解析)
2.存储过程
3.对所有用户输入进行转义
4.其他(检测参数,敏感信息加密,低权账户连接数据库,白名单等)
数字型和字符型
在学习过程中总的感觉字符型较数字型相对麻烦一些,因为存在单引号,容易干扰我们编造注入语句。入列两条语句,第一个为数字型,第二个则是字符型。
select * from student where id=1;
select * from student where id='1';
回显和盲注
就是字面意思,一个会提示你的注入有错误,可以通过floor等报错函数查看具体的错误信息,但是盲注就是正确能够正常显示页面,但是错误时不能正常显示页面,没有提示信息。盲注又分为布尔型和通过页面响应时间来判断,布尔型是根据页面显示差异,响应时间要看响应时间的长短来判断,可以借用延时函数来判断,如sleep函数。
判断是否可以注入
在网页的URL中拼接and1=1或者拼接and1=2尝试在网页中是否能够执行,能够代入执行返回正确界面和错误界面。
select * from students where id=3 and 1=1;
select * from students where id=3 and 1=2;
order by 判断列数与union select联合查询
order by函数可以用来判断页面中总共有多少列,order by函数是一个排序函数,当输入的列数不存在的时候就会返回页面错误的提示。
order by n;
order by n+1 ;
这样数字一直增加直到出现报错信息就可以得到页面中到底存在多少列。
union select是联合查询的意思,可以让查询到的东西显示在指定的列上。(前面查询有几列,后面查询也就有几列,否则就会出现报错信息。)
concat(),concat ws()和group_concat()
concat(str1,str2...)--没有分隔符的串联多列结果。多列变成一列,有几行还是几行。
concat ws(separator,str1,str2.....)--有分隔符的串联多列结果。
页面结果特别少时可以使用这个函数把所有行或者列都连接起来一起输出出来。
group_concat(str1,str2....)函数更加常用--串联多行结果为一行,每行以逗号隔开。把多行串联成一行,变为一行一列输出结果。当页面输出只能输出一行时,可以串联起来输出在一个地方。
非常重要的四个查询语句
1.查出所有数据库的名称:select schema_name from information_schema.schemata;
所有数据库的名称都存在于information_schama这个数据库中的schemata表中。
2.查出数据库中所有的表名:select table_name from information_schema.tables where table_schema='数据库名称';
在information_schema中的tables表中查出所有的table_name数据库是'你需要查询的数据库名称'。
3.查询表中的所有字段:select column_name from information_schema.columns where table_name='表名'and table_schema='数据库名';
在information_schema.columns查出所有字段信息表名和数据库名称写上想要查询的表和数据库。
4.查询自己想要的内容,假设我们要查dvwa数据库users表中user和password列的内容:select user,password from dvwa.users;
在查出数据库名称表名列名之后查内容就显得很容易了。
SQL注入漏洞存在于哪里
SQL是由于参数过滤不严产生的,所以存在参数的地方都有可能存在注入。
寻找漏洞可以用手工注入或者用工具查找。
手工内联注入:注入后原来的语句也会执行。
数字型的内联注入参数
字符串型内联注入参数
手工终止式注入:将原来的部分语句注释掉,注释掉的语句不会被执行。
不同数据库中的注释符
mysql,mssql,Oracle
mysql数据库默认开放端口为3306,默认管理员为root。
mssql数据库默认开放端口为1433,默认管理员为sa。
Oracle数据库默认开放端口为1521,默认管理员为sys。
MySQL内置数据库information_schema的结构
1.information_schema是MySQL自带的一个信息数据库,其保存着关于MySQL服务器所维护的所有其他数据库的信息,如数据库名,数据库的表,表栏的数据类型与访问权限等。也就是说当你建立一个新的数据库,或者在已有的数据库中增删改表的话,都会记录在information_schema库中。
2.information_schema数据库主要表说明:
SCHEMATA表:提供了当前mysql实例中所有数据库的信息。是show databases的结果取之此表。
TABLES表:提供了关于数据库中的表的信息(包括视图)。详细表述了某个表属于哪个schema,表类型,表引擎,创建时间等信息。是show tables from schemaname的结果取之此表。
COLUMNS表:提供了表中的列信息。详细表述了某张表的所有列以及每个列的信息。是show columns from schemaname.tablename的结果取之此表。
STATISTICS表:提供了关于表索引的信息。是show index from schemaname.tablename的结果取之此表。
USER_PRIVILEGES(用户权限)表:给出了关于全程权限的信息。该信息源自mysql.user授权表。是非标准表。
SCHEMA_PRIVILEGES(方案权限)表:给出了关于方案(数据库)权限的信息。该信息来自mysql.db授权表。是非标准表。
TABLE_PRIVILEGES(表权限)表:给出了关于表权限的信息。该信息源自mysql.tables_priv授权表。是非标准表。
COLUMN_PRIVILEGES(列权限)表:给出了关于列权限的信息。该信息源自mysql.columns_priv授权表。是非标准表。
CHARACTER_SETS(字符集)表:提供了mysql实例可用字符集的信息。是SHOW CHARACTER SET结果集取之此表。
COLLATIONS表:提供了关于各字符集的对照信息。
COLLATION_CHARACTER_SET_APPLICABILITY表:指明了可用于校对的字符集。这些列等效于SHOW COLLATION的前两个显示字段。
TABLE_CONSTRAINTS表:描述了存在约束的表。以及表的约束类型。
KEY_COLUMN_USAGE表:描述了具有约束的键列。
ROUTINES表:提供了关于存储子程序(存储程序和函数)的信息。此时,ROUTINES表不包含自定义函数(UDF)。名为“mysql.proc name”的列指明了对应于INFORMATION_SCHEMA.ROUTINES表的mysql.proc表列。
VIEWS表:给出了关于数据库中的视图的信息。需要有show views权限,否则无法查看视图信息。
TRIGGERS表:提供了关于触发程序的信息。必须有super权限才能查看该表。
SQL盲注
当遇见SQL盲注时,没有回显信息我们可以节注ascii码比较大小来猜数据库,猜表名,猜列名然后根据页面返回情况最后得到有用的信息。盲注还分为布尔型和时间型,布尔型盲注能根据页面返回正确与否来观察信息是否正确,但是时间型需要根据返回时间的长短来看信息的正确与否,页面是没有任何变化的。
常用的几个函数有:
count()--统计有多少个结果的函数。
length()--判断数据库,表,等数据长度使用。
ascii()--将字符转化为ascii编码可以比较大小。
字符串截取函数:
mid(m,n)--从该字符串的第m个字符取n个字符。
substr(),substring()函数和mid()函数用法相同,left(string,length)截取字符串从左边开始的指定length长度。
limit(m,n)--m代表从第几行开始取,代表取几行。
sleep()--时间型注入可以借助sleep()函数来判断正确和错误。sleep()函数的特点是,如果查询语句是错误的sleep函数不执行,所以响应时间非常的短,但是如果查询语句是正确的,就会延时sleep函数规定的时间。
if(expr1,expr2,expr3)如果1为真,则执行函数expr2,否则执行expr3。