<kbd id="afajh"><form id="afajh"></form></kbd>
<strong id="afajh"><dl id="afajh"></dl></strong>
    <del id="afajh"><form id="afajh"></form></del>
        1. <th id="afajh"><progress id="afajh"></progress></th>
          <b id="afajh"><abbr id="afajh"></abbr></b>
          <th id="afajh"><progress id="afajh"></progress></th>

          AES加密的安全問題

          共 4604字,需瀏覽 10分鐘

           ·

          2021-10-25 19:10

          關(guān)注、星標(biāo)公眾號,直達(dá)精彩內(nèi)容

          來源:https://www.anquanke.com/post/id/173088

          整理:技術(shù)讓夢想更偉大?| 李肖遙

          ?

          大家好,我是肖遙,最近又遇到了坑,AES加密,如果大家曾經(jīng)搞過,歡迎交流,下面是我整理了一些AES加密的相關(guān)知識,不止于技術(shù)。


          aes加密簡介


          AES算法全稱Advanced Encryption Standard,是DES算法的替代者,旨在取代DES成為廣泛使用的標(biāo)準(zhǔn),于2001年11月26日發(fā)布于FIPS PUB 197,并在2002年5月26日成為有效的標(biāo)準(zhǔn)。2006年,高級加密標(biāo)準(zhǔn)已然成為對稱密鑰加密中最流行的算法之一。


          AES是典型的對稱加密算法,對稱加密不同于md5 sha的哈希摘要算法,對稱加密是可逆的,通常是明文+密鑰,再利用算法來加密成密文,如果要還原也很簡單,只要根據(jù)密鑰+密文+生成算法的逆運(yùn)算,即可解出,對稱加密特點(diǎn)為可逆,并且加密解密都是使用同一個密鑰,而非對稱加密則是公鑰私鑰加解密模式這里不做討論。

          ?

          aes加密五種模式


          aes加密的方式有五種工作體制。


          1.電碼本模式(Electronic Codebook Book (ECB))

          這種模式主要是將明文劃分為幾個明文段,分塊加密,但是加密密鑰是相同的。


          2.密碼分組鏈接模式(Cipher Block Chaining (CBC))

          這種模式是先將明文切分成若干小段,然后每一小段與初始塊或者上一段的密文段進(jìn)行異或運(yùn)算后,再與密鑰進(jìn)行加密。


          3.計算器模式(Counter (CTR))


          4.密碼反饋模式(Cipher FeedBack (CFB))


          5.輸出反饋模式(Output FeedBack (OFB))


          其中分組如,aes-128-ecb即為16字節(jié)為一組,16字節(jié)即為128位。


          其他三種模式較為復(fù)雜,本文僅討論前兩種加密的安全性。

          ?

          aes-ecb加密



          aes-ecb加密是將一段明文,按照固定長度分組,然后對每一個分組,按照算法使用固定的密鑰進(jìn)行加密。假設(shè)123456加密。那么123為一組加密,456為一組加密,然后兩段明文加密后的密文拼在一起,就算完整的密文。


          注意:這里每一組的加密都是使用相同的密鑰,相同的算法,所以在這種機(jī)制下,很可能出現(xiàn)安全問題。


          比如:在身份認(rèn)證中,查詢用戶是否是管理員還是普通用戶,如果is_root=1則為管理員,如果不為1則為普通用戶,如果采用aes-ecb加密,對原文進(jìn)行分組加密。


          明文:user_id:1.000000 is_root:0(其中is_root來判斷是否為管理員。)  然后用一段密鑰加算法進(jìn)行加密。

          這種提交的加密數(shù)據(jù)是在cookie中提交,明文不可控,但是密文是可控的,但由于是進(jìn)行分組進(jìn)行,所以我們可以推算出每一分組明文對應(yīng)的密文,假設(shè)明文八個一組來進(jìn)行加密,分組后變?yōu)?(提示:僅僅是假設(shè)理想情況八位,實際并不是)


          第一組:is_user 
          第二組:1.000000
          第三組: is_root:
          第四組:0(不夠的八位自動填充)

          其中user_id 通常情況下我們前端可以修改,進(jìn)行修改為1.000000,此時原文被加密之后為四組 每組為八個數(shù)字的密文

          假設(shè)加密后密文為

          c4ca4238a0b923820dcc509a6f75849b 在cookie中被提交,將密文分為四組

          c4ca4238
          a0b92382
          0dcc509a
          6f75849b

          此時密文我們是可控的,如果正常提交,服務(wù)器解密之后為user_id:1.000000 is_root:0,很顯然我們不是管理員,但是如果將第二組密文和第四組密文替換呢,那么user_id就是0,is_root就是1.000000。服務(wù)器就解析為user_id:0xxxxxxx(xx為填充字符) is_root:1.000000,顯然我們不需要知道密鑰,同樣可以進(jìn)行繞過。


          還有一則在轉(zhuǎn)賬中,如果采用aes-128-ecb加密,在cookie中使用ecb分組加密,比如


          付款人賬戶:
          XXX //假設(shè)密文abc
          收款人賬戶:
          XXX //假設(shè)密文efg


          試想一下,一旦這個分組是剛好分為四組,我們僅僅將abc與efg交換,那不就造成了支付收款反轉(zhuǎn),幾乎不需要什么技術(shù)就可以造成嚴(yán)重的攻擊。


          ctf-案例


          接下來以真實題目來進(jìn)行詳解。


          ctf address:https://mixer-f3834380.challenges.bsidessf.net/(國外的一道ctf)



          首先嘗試輸入admin admin 登陸。



          返回內(nèi)容重點(diǎn)為紅色框內(nèi)的東西,需要使得第三個參數(shù) is_admin=1即可獲得flag,但是session cookie并不是這個題關(guān)注的點(diǎn),接下來就是抓包分析參數(shù)。修改參數(shù)。



          經(jīng)測試修改url,get cookie post傳參都不能改變is_admin的值,所以只有一種可能,是在cookie里的user參數(shù)里加密了,然后傳遞給服務(wù)器,我們get參數(shù)傳入的賬號密碼被服務(wù)器端加密,然后服務(wù)器返回來加密后的user信息。


          接下來測試是何種加密,測試為aes-ecb加密,那么是如何確定的呢,由于ecb是分組加密,所以一旦一組的密文我們修改了,其他組的密文解密之后是正常的,而被我們修改了的密文解密會是亂碼,所以我們隨便修改下user參數(shù)。



          可以看到報錯,并且第一組的密文解密后是亂碼,而其他組的加密解密后為正常,所以猜測這一定是aes-ecb的分組加密的方式,此時,我們應(yīng)該先確定分組,幾個為一組,先破壞第一組加密然后破壞第二組加密,然后確定解密后json數(shù)據(jù)為,


          {"first_name":"admin","last_name":"admin","is_admin":0}

          總共為55個字符,


          服務(wù)器密文為:d37c125ab4eae2ed02428d6d619016b06500bafffbeebe0c011977ad06c6946a45ba82569e93332195a36e61ae1fe26b325f7afd1eaa5ee8bb11efe6eebc5b54

          為128個字符,五十五個字符補(bǔ)位為64個字符,分組測試破壞每一組,測試到一組明文16個字符,加密密文為32個字符。


          明文分為四組,一組16個字符,密文分為四組,一組32個字符。


          d37c125ab4eae2ed
          02428d6d619016b0
          6500bafffbeebe0c
          011977ad06c6946a
          45ba82569e933321
          95a36e61ae1fe26b
          325f7afd1eaa5ee8
          bb11efe6eebc5b54


          可控的范圍是我們輸入的賬號密碼 admin admin。


          {“first_name”:” 為十五個字符,我們首先構(gòu)造賬號為 a1.0000000000000}

          其中a是為了填充第一組,這樣第一組就是{“first_name”:”a,這樣剩下的1.0000000000000}就是十六個字符為一組,第二組就是1.0000000000000},這樣服務(wù)器加密后返回的第33-64位加密就是1.0000000000000},我們讓服務(wù)器幫我們加密,這樣我們就不需要知道密鑰和算法,讓服務(wù)器幫我們加密任何我們想要的東西,提交數(shù)據(jù)。



          可以看到服務(wù)器返回了加密后的內(nèi)容。我們截取第33位-64位字符。即為1.0000000000000}的密文。


          3af6e4a9e05c702b02f9f4288c1c605c


          接下來就是需要填充位數(shù)。我們讓服務(wù)器解密的json數(shù)據(jù)最后的0}為第65 66位,因為如果這樣的話,前64位剛好是四組,65 66為一組,正好將它32位的密文替換成我們構(gòu)造的密文。


          {“first_name”:”admin”,”last_name”:”admin”,”is_admin”:0}


          五十五位的字符串,我們讓好賬號變?yōu)閍dmin12345678900,那么字符串就是66位,正好符合多余出來的兩位是0},最后這兩位被填充之后的密文同樣是32位,這樣就可以替換我們構(gòu)造的32位密文。



          可以看到服務(wù)器構(gòu)造成功得到flag。


          總結(jié)一下上面思路,我們根據(jù)每一組的加密密文長度固定明文長度固定,所以填充位數(shù),然后讓我們想要的數(shù)據(jù)成為單獨(dú)的一組,讓服務(wù)器進(jìn)行加密,這樣我們就可控制任意明文加密,然后修改cookie里提交的密文,填充字節(jié),讓我們需要的密文位置成為單獨(dú)的一組,然后替換我們之前構(gòu)造的一組數(shù)據(jù),這樣就可以繞過。

          此題值得一題的是雙引號單引號反斜線等被過濾了,所以師傅們其他需要引入雙引號等的不用嘗試了。

          ?

          aes-cbc加密


          這種模式是先將明文切分成若干小段,然后每一小段與初始塊或者上一段的密文段進(jìn)行異或運(yùn)算后,再與密鑰進(jìn)行加密。aes-



          IV:用于隨機(jī)化加密的比特塊,保證即使對相同明文多次加密,也可以得到不同的密文。


          秘鑰:用于加密。


          密文塊0:第一組密文被加密后的內(nèi)容。(同樣也是第二組明文加密過程中的IV)

          cbc加密方式不難理解,將一串明文進(jìn)行分組,舉例 123456789


          123為第一組,456為第二組,789為第三組,將123與IV異或加密(加密中IV只在第一次異或有用),得到的異或后的密文與密鑰加密,假設(shè)此時第一組加密的最終密文為abc,那么456先于第一組的密文abc異或加密,得到的異或密文在與密鑰加密,假設(shè)第二組最終密文為def,往復(fù)循環(huán),def與第三組明文異或,然后和密鑰加密,假設(shè)密文ghi,那么最終密文就是


          abcdefghi并且將iv發(fā)送。


          其中值得一提的是初始始化向量IV每次隨即初始化,所以即使相同的字符串也不會有相同的密文。


          cbc字節(jié)反轉(zhuǎn)攻擊


          那么這種在這種加密的方式下,并不安全,問題出在異或加密這里,在講解字節(jié)反轉(zhuǎn)攻擊前先了解下異或加密。


          異或 xor 符號表示為 ^ ,計算機(jī)中 兩個數(shù)字異或,相同為0,不同為1。1^1=0 0^1=1


          如果是字母異或加密,a^b,那么首先轉(zhuǎn)化為ascii編碼,然后二進(jìn)制,對每一位進(jìn)行異或得到的結(jié)果轉(zhuǎn)為十進(jìn)制,在ascii編碼出來。



          異或有一個特性,任意值與自己本身做異或運(yùn)算的結(jié)果都是0,任意值與0做異或運(yùn)算的結(jié)果都是自己。本身a^b=亂七八糟,a^a則為空,但是a^a^任意字母=任意字母。



          在CBC解密中,如圖A是第一組的密文,B是第二組被解密的密文(未異或),C是明文。C=A^B。那么B=C^A,且A^B^C=0。如果我們更改A,A為我們可控的密文,C=A^B,如果我們使A=B^X,B=C^A,所以A=C^A^X,C=C^A^X^B=B^X^B=X。這里X是我們需要的任意字符,這便是CBC字節(jié)反轉(zhuǎn)攻擊的核心,這樣一來C的明文就完全可控了。


          簡單的登錄-cbc字節(jié)反轉(zhuǎn)


          原理說了很多,那么接下來實戰(zhàn)一下。


          實驗吧題目:http://ctf5.shiyanbar.com/web/jiandan/index.php



          首先,輸入框隨便輸入,然后發(fā)送請求抓包,看到返回包的頭請求有tips,test.php。訪問test.php即可看到源碼。


          define("SECRET_KEY", '***********');define("METHOD", "aes-128-cbc");error_reporting(0);include('conn.php');function sqliCheck($str){    if(preg_match("/\|,|-|#|=|~|union|like|procedure/i",$str)){        return 1;    }    return 0;}function get_random_iv(){    $random_iv='';    for($i=0;$i<16;$i++){        $random_iv.=chr(rand(1,255));    }    return $random_iv;}function login($info){    $iv = get_random_iv();    $plain = serialize($info);    $cipher = openssl_encrypt($plain, METHOD, SECRET_KEY, OPENSSL_RAW_DATA, $iv);//$plain為要加密的明文,METHOD加密方法,SECRET_KEY是秘鑰,OPENSSL_RAW_DATA為數(shù)據(jù)格式,$iv隨機(jī)生成的初始化向量。    setcookie("iv", base64_encode($iv));    setcookie("cipher", base64_encode($cipher));}function show_homepage(){    global $link;    if(isset($_COOKIE['cipher']) && isset($_COOKIE['iv']))    {        $cipher = base64_decode($_COOKIE['cipher']);        $iv = base64_decode($_COOKIE["iv"]);
          if($plain = openssl_decrypt($cipher, METHOD, SECRET_KEY, OPENSSL_RAW_DATA, $iv)) { $info = unserialize($plain) or die("

          base64_decode('".base64_encode($plain)."') can't unserialize

          "
          );
          $sql="select * from users limit ".$info['id'].",0"; $result=mysqli_query($link,$sql);
          if(mysqli_num_rows($result)>0 or die(mysqli_error($link))){ $rows=mysqli_fetch_array($result); echo '

          Hello!'.$rows['username'].'

          '
          ;
          }
          else{ echo '

          Hello!

          '
          ;
          } } else { die("ERROR!"); } }}if(isset($_POST['id'])){ $id = (string)$_POST['id']; if(sqliCheck($id)) die("

          sql inject detected!

          "
          );
          $info = array('id'=>$id); login($info); echo '

          Hello!

          '
          ;
          }else{ if(isset($_COOKIE["iv"])&&isset($_COOKIE['cipher'])){ show_homepage(); }else{ echo '
          '; }}
          ?>


          前提:這一關(guān)不是單純注入饒過的,肯定要利用cbc字節(jié)反轉(zhuǎn)攻擊。


          1.首先直接看在哪里可以得到flag,沒傳入ID參數(shù)的時候,如果cookie建立了iv 和 cipher參數(shù),那么就可以調(diào)用show_homepage,執(zhí)行sql查詢,flag在數(shù)據(jù)庫里查詢。


          2.但是肯定要傳參id,先生成iv 和 cipher,將id=X該數(shù)組進(jìn)行序列化之后,以序列化結(jié)果和一個bs64編碼隨機(jī)數(shù)iv進(jìn)行cbc加密生成密文cipher,加密算法為aes-128-cbc,此時就要考慮cbc字節(jié)反轉(zhuǎn)了,128位,按十六字節(jié)分組。生成iv和cipher之后url編碼返回請求頭,生成細(xì)節(jié)參考自定義login函數(shù)。


          3.sql查詢語句拼接了一個0,所以我們只要注釋掉0便可進(jìn)行我們的查詢。所以可以利用cbc字節(jié)翻轉(zhuǎn)攻擊更改密文,更改解密后的id,從而繞過進(jìn)行sqlwaf,cookie傳入?yún)?shù) cipher和iv,base64解碼然后aes解密,php反序列化,如果不能反序列化,則輸出base64編碼,否則就sql語句拼接查詢。如果有結(jié)果回顯,否則輸出hello。


          綜上,只要我們能夠CBC進(jìn)行字節(jié)反轉(zhuǎn)就可以執(zhí)行sql查詢,就可以進(jìn)行查詢flag。


          接下來第一步首先要cbc字節(jié)反轉(zhuǎn),修改密文中的id。不妨先測試下位數(shù),如果傳入id=12(因為我們要修改為1#),則序列化后內(nèi)容為


          a:1:{s:2:"id";s:2:"12";}


          由于我們需要分組,aes-128-cbc,128位16字節(jié)分組


          第一組:a:1:{s:2:"id";s:

          第二組:2:"12";}


          10中的0是第二組的第五個字符,所以需要更改第5個字符,右偏移四個字符,第一組也要向右偏移四個字符。接下來就是cbc字節(jié)反轉(zhuǎn)腳本。


          # -*- coding:utf8 -*-
          from base64 import *
          import urllib

          cipher='fn060OBP%2FyLIGYrD9bi%2FlWWAS9RIWvEtALaV26kuB%2F8%3D'#加密后的密文

          cipher_raw=b64decode(urllib.unquote(cipher))#首先urldecode解碼,然后base64解碼

          cipher_raw_list=list(cipher_raw)#將解碼的密文分組

          py=4#偏移量為4
          A=cipher_raw_list[py]#要異或第二組密文的位置
          C='2'#第二組被替換的明文
          X='#'#將第二組替換掉的明文

          cipher_raw_list[py]=chr(ord(A)^ord(C)^ord(X))#將偏移量為4的替換。

          cipher_new=''.join(cipher_raw_list)#使用''將每一個字符連接起來,
          cipher_new=urllib.quote(b64encode(cipher_new))#將替換完的密文base64編碼,urlencode編碼。

          print cipher_new#打印出最終密文


          其中特意將ACX等變量對應(yīng)上文所講的參數(shù)??蓞⒖忌厦鎐bc字節(jié)反轉(zhuǎn)配合圖來理解。然后生成反轉(zhuǎn)后的密文:


          fn060PFP/yLIGYrD9bi/lWWAS9RIWvEtALaV26kuB/8%3D


          此時提交密文發(fā)送服務(wù)器會返回base64編碼字符串無法反序列化。


          原因為下面這句。



          接下來我們需要修改IV,原理很簡單,我們分為兩組來進(jìn)行加解密,第一組密文只參與第二組的異或,第一組修改完成后,第二組的解密是完全沒有問題的,但是第一組被我們修改了一個字符,但是異或的IV還是原來的IV,必須要修改IV才能使第一組正常異或,得到結(jié)果。還是上述原理,三次異或,控制想要的結(jié)果。


          這里在看圖,



          A:這里特別要說明注意,A是我們第一次字節(jié)反轉(zhuǎn)之后的明文(序列化狀態(tài))
          B:原來的IV
          C:字節(jié)反轉(zhuǎn)后解密后的第一組(未被異或)
          D: 正常的序列化字符串 ‘a(chǎn):1:{s:2:”id”;s:’
          E:新的IV


          A=B^C,因為我們A是字節(jié)反轉(zhuǎn)這里我們可以看到,IV是原來的IV,但是A和C都是字節(jié)反轉(zhuǎn)后的,所以A必然是個無法反序列化的明文,我們修改B也就是IV,使得異或得到正常的序列化字符串。


          B=A^C,我們需要得到的結(jié)果是D=E^C,而C=B^A,所以D=E^B^A,那么E=B^A^D。//建議初學(xué)者自己多分析下邏輯,多寫寫,干想很頭疼。


          接下來是IV修改的腳本。

          # -*- coding:utf8 -*-__author__='[email protected]'
          from base64 import *import urllibiv='erUDGVSvM4Kab3ztg8vT8Q%3D%3D'B=b64decode(urllib.unquote(iv))D='a:1:{s:2:"id";s:'A=b64decode('eFoXA0j/x2Em/bhfgeLzXjI6IjEjIjt9')iv_new=''for i in range(16): iv_new+=chr(ord(A[i])^ord(D[i])^ord(B[i]))iv_new=urllib.quote(b64encode(iv_new))
          print iv_new


          替換掉原來的IV,即可正常sql查詢。



          至此,此題的cbc反轉(zhuǎn)我們已經(jīng)完成了,剩下的注入原理一樣,注入不是本題的目的,也就不再發(fā)剩下的腳本了。CBC還是要自己寫一下用圖理解一下。


          其余加密問題,后續(xù)我會補(bǔ)充到本文。


          參考:https://www.yourhome.ren/index.php/sec/366.html
          參考:實驗吧pcat師傅的writeup

          ???????????????? ?END ?????????????????

          關(guān)注我的微信公眾號,回復(fù)“加群”按規(guī)則加入技術(shù)交流群。

          歡迎關(guān)注我的視頻號:


          點(diǎn)擊“閱讀原文”查看更多分享,歡迎點(diǎn)分享、收藏、點(diǎn)贊、在看。

          瀏覽 47
          點(diǎn)贊
          評論
          收藏
          分享

          手機(jī)掃一掃分享

          分享
          舉報
          評論
          圖片
          表情
          推薦
          點(diǎn)贊
          評論
          收藏
          分享

          手機(jī)掃一掃分享

          分享
          舉報
          <kbd id="afajh"><form id="afajh"></form></kbd>
          <strong id="afajh"><dl id="afajh"></dl></strong>
            <del id="afajh"><form id="afajh"></form></del>
                1. <th id="afajh"><progress id="afajh"></progress></th>
                  <b id="afajh"><abbr id="afajh"></abbr></b>
                  <th id="afajh"><progress id="afajh"></progress></th>
                  啪啪啪国产网站 | 五月777| 菠萝视频| 操婷婷逼 | 野外体内射精视频 |