iT邦幫忙

2024 iThome 鐵人賽

DAY 29
0
Security

picoCTF系列 第 29

[Day 29] rsa_oracle

  • 分享至 

  • xImage
  •  

看到題目,題目要求我們將 password 解碼出來,提示告訴我們可以用選擇明文攻擊還有 openssl 來解密。
https://ithelp.ithome.com.tw/upload/images/20240922/20168342zjQBOZGqLQ.png
hint 1:Crytography Threat models: chosen plaintext attack.
hint 2:OpenSSL can be used to decrypt the message. e.g openssl enc -aes-256-cbc -d ...
hint 3:The key to getting the flag is by sending a custom message to the server by taking advantage of the RSA encryption algorithm.
hint 4:Minimum requirements for a useful cryptosystem is CPA security.

查看下載了甚麼,並用 cat 檢視題目給的 password.encsecret.enc

$ ls -l 
-rw-rw-r--  1 peggggy-picoctf peggggy-picoctf     154 Mar 12 00:36 password.enc
-rw-rw-r--  1 peggggy-picoctf peggggy-picoctf      64 Mar 12 00:36 secret.enc
$ cat password.enc 
2336150584734702647514724021470643922433811330098144930425575029773908475892259185520495303353109615046654428965662643241365308392679139063000973730368839
$ cat secret.enc 
Salted__jX9V)pT3Ͼq$qEs5n\K5=%c  Q9s1!quM04

試著連上 webshell 後,發現可以加解密文字。

$  nc titan.picoctf.net 58343
*****************************************
****************THE ORACLE***************
*****************************************
what should we do for you? 
E --> encrypt D --> decrypt. 
E
enter text to encrypt (encoded length must be less than keysize): 123
123

encoded cleartext as Hex m: 313233

ciphertext (m ^ e mod n) 1599246634826874851095335841874633680383690362307908452095323796981689155124475346861967384109287536222761421010922720299434706521748860299773886324674588

what should we do for you? 
E --> encrypt D --> decrypt. 
D
Enter text to decrypt: 1599246634826874851095335841874633680383690362307908452095323796981689155124475346861967384109287536222761421010922720299434706521748860299773886324674588
decrypted ciphertext as hex (c ^ d mod n): 313233
decrypted ciphertext: 123

試著將 password 和 secret 解密,確定都沒有辦法解碼。

$ nc titan.picoctf.net 58343
*****************************************
****************THE ORACLE***************
*****************************************
what should we do for you? 
E --> encrypt D --> decrypt. 
D
Enter text to decrypt: 2336150584734702647514724021470643922433811330098144930425575029773908475892259185520495303353109615046654428965662643241365308392679139063000973730368839
Lol, good try, can't decrypt that for you. Be creative and good luck

what should we do for you? 
E --> encrypt D --> decrypt. 
D
Enter text to decrypt: Salted__jX9V)pT3Ͼq$qEs5n\K5=%c  Q9s1!quM04

於是想起 hint 2,再嘗試使用 openssl 解碼 secret.enc,發現要填入 password。

於是我們從 hint1 聯想,猜測應該是要用選擇明文攻擊破解 password。

$ openssl enc -aes-256-cbc -d -in secret.enc 
enter AES-256-CBC decryption password:

在要講 RSA 的 CPA ( 選擇明文攻擊 ) 前,我們先來複習 RSA。

一般 RSA 是以下步驟:

  1. 選擇兩個大的質數 p 和 q, N = p * q
  2. 得 r = (p-1) (q-1)
  3. 選擇 < r 的質數 e,並求得 𝑒 關於 𝑟 的模反元素,命名為𝑑(求𝑑, 令 𝑒𝑑 ≡ 1(mod 𝑟))。

令密文 = C,明文 = M

C = M^e mod N

M = C^d mod N

那選擇明文攻擊套用在 RSA 是怎麼使用呢?首先確定我們的已知和要得到的資訊是甚麼。

我們已知密文就是得到的 password.enc 的內容,也就是 C,而我們想要知道的是 M。

然後再進行選擇明文的過程,可以參考下圖 ( 資料來源: CPA ),並且以下的 t,想像成我們欲知的 M。
https://ithelp.ithome.com.tw/upload/images/20240922/201683428FMiyG56kt.png

簡單來說,就是選擇某個明文,並且和已知的密文相乘,一起加密,最後解密出來的內文可以推回已知密文中的明文為何。

於是可以得到底下的 pwn script。

from pwn import *

with open("password.enc") as file:
    c = int(file.read())

context.log_level='critical'
p = remote("titan.picoctf.net", 61923)

p.recvuntil(b"E --> encrypt D --> decrypt.")
p.sendline(b"E")

p.recvuntil(b"(encoded length must be less than keysize): ")
# choose hex(02) as chosen plantext
p.sendline(b"\x02")

p.recvuntil(b"ciphertext (m ^ e mod n) ")
c2 = int(p.recvline())

p.recvuntil(b"E --> encrypt D --> decrypt.")
p.sendline(b"D")

p.recvuntil(b"decrypt: ")
# M^e (password.enc) * 2^e (chosen plaintext)
p.sendline(str(c * c2).encode())

p.recvuntil(b"decrypted ciphertext as hex (c ^ d mod n): ")
# p.recvuntil = M*2 mod N, and we want to get M
password = int(p.recvline(), 16) // 2
print( hex(password) )

# bytes.fromhex(str)
# hex(password)[2:], to remove '0x'
password = bytes.fromhex( hex(password)[2:]).decode('ascii')
print("Password:", password)

執行 script.py 後,會得到 password,並且依照提示 1,使用 openssl 將 secret.enc 解密,就可以得到 flag 了。

$ python3 script.py 
Hex password 0x3630663530
Password: 60f50
$ openssl enc -aes-256-cbc -d -in secret.enc 
enter AES-256-CBC decryption password:
*** WARNING : deprecated key derivation used.
Using -iter or -pbkdf2 would be better.
picoCTF{su((3ss_(r@ck1ng_r3@_60f50766}

小結:

了解選擇明文攻擊。


上一篇
[Day 28] Mob psycho
下一篇
[Day 30] Classic Crackme 0x100
系列文
picoCTF30
圖片
  直播研討會
圖片
{{ item.channelVendor }} {{ item.webinarstarted }} |
{{ formatDate(item.duration) }}
直播中

尚未有邦友留言

立即登入留言