less28

本关除了过滤注释符和空格,还将连续的union select给过滤了,我们可以使用双写绕过。

%a0的问题

在别人的博客中我们发现有人使用%a0来代替空格是不会被过滤的,查询资料发现,是因为php版本不同在php5.2.17中,%a0是可以被解析成空格的,而php7中却不行。

less29-31

这三关除了字符注入类型不同,其他方面几乎是一致的。

源代码中出现了$qs = $_SERVER['QUERY_STRING'];

当这行代码执行时,它会从当前请求的 URL 中提取查询字符串,并将其存储在 $qs 变量中。这样你就可以在PHP脚本中使用这个查询字符串来获取请求参数,进行条件判断,或者执行其他逻辑。例如,在 URL http://example.com/page.php?name=John&age=30 中,查询字符串是 name=John&age=30

当输入正常参数时,网页返回正常信息,当输入单引号时,网页会被切换到hacked.php,应该是注入参数被WAF防御了。查看源码

login.php:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
function whitelist($input)
{
$match = preg_match("/^\d+$/", $input);
if($match)
{
//echo "you are good";
//return $match;
}
else
{
header('Location: hacked.php');
//echo "you are bad";
}
}
function java_implimentation($query_string)
{
$q_s = $query_string;
$qs_array= explode("&",$q_s);

foreach($qs_array as $key => $value)
{
$val=substr($value,0,2);
if($val=="id")
{
$id_value=substr($value,3,30);
return $id_value;
echo "<br>";
break;
}

}

}

whitelist():

是用于检查输入是否为纯数字,如果不是则跳转到 hacked.php

java_implimentation():

explode()把字符串打散为数组,例如$str=”Hello World”在explode(“ “;$str)函数作用下就被打散成了Array([0] => Hello ,[1] => World)

而foreach()函数主要作用就是遍历数组,将数组被分割的数组一一输出出来。这个函数有两种语法:

  • foreach (array_expression as $value):每次循环中,当前单元的值被赋给 $value 并且数组内部的指针向前移一步
  • foreach (array_expression as $key => $value):同语句一,同时当前单元的键名在每次循环中赋值给$key。

这两个自定义函数的效果就是将语句以“&”为标识分割开,然后再分割开的数组的前两位找id值,如果找到了就截取这个数组的第4位到30位的长度交给preg_match()进行正则匹配。

对此我们可以使用 HTTP 参数污染攻击

原理为:

截图等来自《MySQL注入天书:Less 29》

bc43cb9cc3e035dee1f34323fb0ae1c2

服务器端有两个部分:第一部分为 tomcat 为引擎的 jsp 型服务器,第二部分为 apache 为引擎的 php 服务器,真正提供 web 服务的是 php 服务器。

工作流程为:client 访问服务器,能直接访问到 tomcat 服务器,然后 tomcat 服务器再向 apache 服务器请求数据。数据返回路径则相反。

接下来是参数解析的问题。
问:index.php?id=1&id=2,这时回显是id=1还是id=2呢?
答:apache (php) 解析最后一个参数,即回显id=2;tomcat (jsp) 解析第
一个参数,即回显id=1。

大多数服务器对于参数解析:

09d8f68230d3ee833917982a92d043dd

这里有一个新问题。
问:index.jsp?id=1&id=2,针对这关的两层结构,客户端请求首先过 tomcat,tomcat 解析第一个参数,接下来 tomcat 请求 apache,apache 解析最后一个参数。那么最终返回客户端的是哪个参数?
答:此处应该还是id=2,因为实际上提供服务的是 apache 服务器,返回的数据也应该是 apache 处理的数据。

而在我们实际应用中,也是有两层服务器的情况,那为什么要这么做?是因为我们往往在 tomcat 服务器处做数据过滤和处理,功能类似为一个 WAF。

而正因为解析参数的不同,我们此处可以利用该原理绕过 WAF 的检测。如 payload:index.jsp?id=1&id=0 or 1=1–+,tomcat 只检查第一个参数id=1,而对第二个参数id=0 or 1=1–+不做检查,直接传给了 apache,apache 恰好解析第二个参数,便达到了攻击的目的。

该用法就是 HPP(HTTP Parameter Pollution)即 HTTP 参数污染攻击的一个应用。HPP 可对服务器和客户端都能够造成一定的威胁。

less-30双引号注入,less-31双引号加括号注入,语句构建思路与29关完全一致。

less32-33&35&36

Less 32、33、35、36 都涉及到了对注入参数的转义,在一般情况下是不能注入的。但是当数据库使用 GBK 国标码或者其他编码时,可以使用恶意的参数把用于转义的斜杠“吃掉”变成其他字符,这就是所谓宽字节注入。使用宽字节注入绕过转义之后,其他的注入步骤和 Less 1 相似。

查看源码发现:

1
2
3
4
5
6
7
8
 function check_addslashes($string)
{
$string = preg_replace('/'. preg_quote('\\') .'/', "\\\\\\", $string); //escape any backslash
$string = preg_replace('/\'/i', '\\\'', $string); //escape single quote with a backslash
$string = preg_replace('/\"/', "\\\"", $string); //escape double quote with a backslash

return $string;
}
  • **preg_quote('\\')**:preg_quote 函数用于转义正则表达式中的特殊字符。由于反斜杠(\)在正则表达式中是特殊字符,所以需要先对其进行转义。这里传入的 \\ 实际上表示一个反斜杠字符,因为在 PHP 字符串中,反斜杠本身是转义字符,所以需要用两个反斜杠来表示一个实际的反斜杠。preg_quote('\\') 的结果是 \\,表示匹配一个实际的反斜杠字符。
  • preg_replace:该函数用于执行正则表达式的搜索和替换操作。第一个参数是正则表达式模式,这里是 /\\/,表示匹配字符串中的反斜杠字符。第二个参数是替换字符串,\\\\\\ 在 PHP 字符串中表示两个连续的反斜杠(\\),因为每个反斜杠都需要用两个反斜杠来转义。所以这行代码的作用是将字符串中的每个反斜杠替换为两个反斜杠,还在‘前加上反斜杠以转义,实现反斜杠的转义。

接着是这句代码:
mysql_query("SET NAMES gbk");
这行代码的作用是设置客户端(即PHP脚本)与MySQL数据库服务器之间编码使用GBK国标码。

当数据库的编码采用 GBK 国标码时,虽然单引号还是会加上反斜杠从而被转义,但是 “%df” 会和反斜杠的 URL 编码 “%5C” 闭合,从而构成 GBK 国标码中的汉字“連”,使得用于转义的反斜杠被我们“吃掉”了。

接下来就用联合查询注入

less33和32差不多,less-33与32关的区别在于这关使用了addslashes()函数进行过滤操作,此处的过滤函数是 addslashes() 函数,用于在预定义字符之前添加反斜杠,预定字符有单引号、双引号和反斜杠。

1
2
3
4
5
Copy Highlighter-hljsfunction check_addslashes($string)
{
$string = addslashes($string);
return $string;
}

less35是数值型转义就没用了。

而less-36则是使用了mysql_real_escape_string()进行过滤,本质上都没什么差别。

less34&37

less34是用 **addslashes() **过滤的

less37是用**mysql_real_escape_string()**函数进行过滤

这两个和之前的差不多不过是post传参。