如何调整SQL注入教学演示代码,支持学生执行DROP TABLE注入操作
报错原因
你遇到的报错是因为PHP的mysqli_query默认不支持多语句执行,当你输入带;的堆叠注入语句(比如带DROP TABLE的语句)时,SQL语句被拆分为多条执行,mysqli_query直接执行失败返回布尔值false,后续代码直接把false传入mysqli_num_rows、mysqli_fetch_assoc就触发了参数类型错误。
方案1:修改代码支持堆叠注入(进阶操作)
如果要支持DROP、CREATE这类需要堆叠执行的注入操作,你需要把查询逻辑改为支持多语句执行的写法,修改后代码如下:
//prepare sql - this is a really bad thing to do $sql="SELECT * FROM tblUsers WHERE username = '$user' AND password = '$pass' " ; // leaky log to console console_log($sql); // 改用支持多语句执行的mysqli_multi_query $executeSuccess = mysqli_multi_query($conn, $sql); //leaky log to console console_log($executeSuccess); // 处理多语句结果集 if ($executeSuccess) { // 取第一个SELECT语句的结果集 if ($result = mysqli_store_result($conn)) { if (mysqli_num_rows($result) > 0) { //get the row and turn into an array of strings $row = mysqli_fetch_assoc($result); } mysqli_free_result($result); } // 跳过后续语句的结果集,避免报错 while (mysqli_more_results($conn) && mysqli_next_result($conn)) { if ($result = mysqli_store_result($conn)) { mysqli_free_result($result); } } } else { //if nothing returned, throw them back to the login page echo "Incorrect username or password"; header("Location: login.html"); exit(); }
修改后你输入' OR '1'='1'; DROP TABLE tblUsers;-- 这类堆叠注入语句就可以正常执行DROP操作了。
方案2:不改代码的可用注入语句
如果不修改原有代码,你可以用不需要堆叠执行的注入语句完成更多操作:
- 联合查询注入:先通过
' ORDER BY 1;--、' ORDER BY 2;--测试出原SELECT语句的列数,再用UNION拼接自定义查询拖取数据,例如列数为3时可以输入' UNION SELECT 1,database(),version();--直接获取当前数据库名、数据库版本。 - 报错注入:如果页面会输出SQL执行错误,可以用updatexml、extractvalue函数主动触发报错带出数据,输入
' AND updatexml(1,concat(0x7e,(SELECT GROUP_CONCAT(username) FROM tblUsers),0x7e),1);--就能直接拿到所有用户名。 - 布尔盲注/时间盲注:如果页面没有任何数据回显,也可以通过页面返回的差异、sleep函数的延迟来逐位猜解所有数据,例如输入
' AND IF(SUBSTR(database(),1,1)='t',sleep(5),1);--如果页面加载延迟5秒,就说明当前数据库名的第一个字符是t。
内容的提问来源于stack exchange,提问作者mikki
相关产品推荐
相关产品推荐

