iT邦幫忙

2023 iThome 鐵人賽

DAY 21
0
Security

資安小白的密碼學從0到1-CryptoHack平台解題紀錄系列 第 22

【Day 21】Symmetric CryptoGraphy04 - Symmetric Starter

  • 分享至 

  • xImage
  •  

前言

今天題目為對稱密碼的入門,會解以下兩題,開始吧!
https://ithelp.ithome.com.tw/upload/images/20231001/2016261366QNmeBu41.png

題外話 : 今天因為晚上沒去睡覺,所以終於不是壓線發文惹,感動w
不然都會睡到10點多起來趕

Writeup

Modes of Operation Starter

題目

網址 : https://cryptohack.org/courses/symmetric/block_cipher_starter/
https://ithelp.ithome.com.tw/upload/images/20231001/201626130dGxVrlfHM.png

思路

這題再說,我們前面資料是因為剛好為128bit,所以可以剛好執行AES加密,但如果資料太長了怎麼辦,這時候就要用到操作模式(modes of operation)來解決多區塊的加密
點進題目網址 https://aes.cryptohack.org/block_cipher_starter/
發現了source code跟ECB的流程圖
可以先來看懂source code
https://ithelp.ithome.com.tw/upload/images/20231001/201626138ZY1hJHCaL.png

先來看encrypt_flag()

def encrypt_flag():
    cipher = AES.new(KEY, AES.MODE_ECB)
    encrypted = cipher.encrypt(FLAG.encode())

    return {"ciphertext": encrypted.hex()}

會先創建一個AES 模式為ECB的cipher
之後將FLAG 使用cipher進行加密 並把結果存在encrypted
最後return encrypted.hex()

接下來是decrypt()

def decrypt(ciphertext):
    ciphertext = bytes.fromhex(ciphertext)

    cipher = AES.new(KEY, AES.MODE_ECB)
    try:
        decrypted = cipher.decrypt(ciphertext)
    except ValueError as e:
        return {"error": str(e)}

    return {"plaintext": decrypted.hex()}

會先把讀進來的ciphertext轉為bytes
之後創建一個AES 模式為ECB的cipher
接下來進入try,
將ciphertext 使用cipher進行解密 並把結果存在decrypted
如果出錯就return error
如果順利進行,最後會return decrypted.hex()

解法

旁邊有兩個按鈕(submit),分別按下後會輸出decrypt跟encrypt的結果
所以我們先按下encrypt,看他會噴出甚麼
https://ithelp.ithome.com.tw/upload/images/20231001/20162613fIYajvnNie.png
發現噴出了ciphertext

24e49b0a571db106b3392b0dc7b422b6d284081583603de51865f289806d855a

有了它,可以直接丟上去請它幫我們解密
https://ithelp.ithome.com.tw/upload/images/20231001/20162613PFR3bB3slj.png
得到了plaintext!
由source code可知,出來的結果會是decrypted.hex()
所以我們再把plaintext丟到下面的hex encode/decode
https://ithelp.ithome.com.tw/upload/images/20231001/20162613NtuOGrbSyH.png
即可獲得flag

flag : crypto{bl0ck_c1ph3r5_4r3_f457_!}

Passwords as Keys

題目

網址 : https://cryptohack.org/courses/symmetric/passwords_as_keys/
https://ithelp.ithome.com.tw/upload/images/20231001/20162613oPRKU7j7mO.png

思路

這題跟上一題差不多,就是複雜了一點,key多了一個hash md5的動作,一樣先看source code
https://ithelp.ithome.com.tw/upload/images/20231001/20162613XyykTTp7LI.png
會發現它的key是從"https://gist.githubusercontent.com/wchargin/8927565/raw/d9783627c731268fb2935a731a618aa8e95cf465/words" 字典檔隨機取一個,之後hashmd5後得出的
雖然題目按下encrypt那邊的按鈕後,一樣會噴ciphertext,但這次要解密的話需要輸入password_hash,也就是上面講到的key
那這次要怎麼求出flag呢?
可以自己寫一個程式,之後利用迴圈暴力解

解法

先看source code,看他的整個decrypt過程,包括KEY是怎麼生成的
他是隨機從words裡面取一個,之後
KEY = hashlib.md5(keyword.encode()).digest()
進入到decrypt
把ciphertext跟key都從hex轉為bytes

因為網站指定讀進來的只能是hex
https://ithelp.ithome.com.tw/upload/images/20231001/20162613S7FrNoy2ZZ.png

之後的code就跟上一題一模一樣惹

了解後首先要先去載他key的使用到字典檔
之後因為我們不知道他從字典檔中選了哪一個,所以我們利用迴圈一個一個試試看,然後看他的結果,如果對的話,字串裡面一定會有"crypto{"在

  • 迴圈code
    password先經過hashmd5處理後存到key
    之後AES ECB解密,並把結果存到decrypted
    最後如果decrypted裡面有"crypto{"那麼就return decrypted.decode()

words : 字典檔

    for password in words: 
        key = hashlib.md5(password.encode()).digest()
        cipher = AES.new(key, AES.MODE_ECB)
        decrypted = cipher.decrypt(ciphertext)
        if b"crypto{" in decrypted :
            return decrypted.decode()
  • 完整code
import hashlib
from Crypto.Cipher import AES
#open("字典檔路徑")
with open("words.txt") as f:
    words = [w.strip() for w in f.readlines()]
 
ciphertext = "c92b7734070205bdf6c0087a751466ec13ae15e6f1bcdd3f3a535ec0f4bbae66"

def decrypt(ciphertext):
    ciphertext = bytes.fromhex(ciphertext)
    
    for password in words: 
        key = hashlib.md5(password.encode()).digest()
        cipher = AES.new(key, AES.MODE_ECB)
        decrypted = cipher.decrypt(ciphertext)
        if b"crypto{" in decrypted :
            return decrypted.decode()
   
def main():
    print(decrypt(ciphertext))

if __name__ == "__main__" :
    main()
  • output
    https://ithelp.ithome.com.tw/upload/images/20231001/20162613A2H2pvx0cD.png

flag : crypto{k3y5__r__n07__p455w0rdz?}

統整

python AES加解密的使用

  • 函式庫
from Crypto.Cipher import AES
  • AES加密(MOD : ECB)

把FLAG加密,存到encrypted

cipher = AES.new(KEY, AES.MODE_ECB)
encrypted = cipher.encrypt(FLAG.encode())
  • AES解密(MOD : ECB)

把ciphertext解密,存到decrypted

    cipher = AES.new(KEY, AES.MODE_ECB)
    decrypted = cipher.decrypt(ciphertext)

小結

今天題目為入門,還比較不用去了解ECB,明天應該會正式接觸到ECB,這系列題目做完後,應該會做一下操作模式(modes of operation)的筆記統整!


上一篇
【Day 20】Symmetric CryptoGraphy03 - AES實作
下一篇
【Day 22】小小小小~回顧
系列文
資安小白的密碼學從0到1-CryptoHack平台解題紀錄31
圖片
  直播研討會
圖片
{{ item.channelVendor }} {{ item.webinarstarted }} |
{{ formatDate(item.duration) }}
直播中

尚未有邦友留言

立即登入留言