1. 程式人生 > 其它 >CTF中RSA題型解題思路及技巧

CTF中RSA題型解題思路及技巧

0x01 RSA演算法簡介

為了方便小白咀嚼後文,這裡先對RSA金鑰體制做個簡略介紹(簡略因為這不是本文討論的重點)

  1. 選擇兩個大素數p和q,計算出模數N = p * q
  2. 計算φ = (p−1) * (q−1) 即N的尤拉函式,然後選擇一個e (1<e<φ),且e和φ互質
  3. 取e的模反數為d,計算方法: e * d ≡ 1 (mod φ)
  4. 對明文m進行加密:c = pow(m, e, N),得到的c即為密文
  5. 對密文c進行解密,m = pow(c, d, N),得到的m即為明文

整理一下得到我們需要認識和記住的引數

  • p 和 q :大整數N的兩個因子(factor)
  • N:大整數N,我們稱之為模數(modulus
  • e 和 d:互為模反數的兩個指數(exponent)
  • c 和 m:分別是密文和明文,這裡一般指的是一個十進位制的數

然後我們一般稱

  • (N,e):公鑰
  • (N,d):私鑰

0x02 CTF中的RSA題型

CTF中的RSA題目一般是將flag進行加密,然後把密文(即c)和其他一些你解題需要的資訊一起給你,你需要克服重重難關,去解密密文c,得到flag(即m),一般有下列題型

公鑰加密文

這是CTF中最常見最基礎的題型,出題人會給你一個公鑰檔案(通常是以.pem或.pub結尾的檔案)和密文(通常叫做flag.enc之類的),你需要分析公鑰,提取出(N,e),通過各種攻擊手段恢復私鑰,然後去解密密文得到flag。

文字文件

對於第一種題型,耿直點的出題人直接給你一個txt文字文件,裡面直接寫出了(N,e,c)所對應的十進位制數值,然後你直接拿去用就行了。當然也不都是給出(N,e,c)的值,有時還會給出其他一些引數,這時就需要思考,這題具體考察的什麼攻擊方法

pcap檔案

有時出題人會給你一個流量包,你需要用wireshark等工具分析,然後根據流量包的通訊資訊,分析題目考察的攻擊方法,你可以提取出所有你解題需要用到的引數,然後進行解密

本地指令碼分析

題目會給你一個指令碼和一段密文,一般為python編寫,你需要逆向檔案流程,分析指令碼的加密過程,寫出對應的解密指令碼進行解密

遠端指令碼利用

這種題型一般難度較大。題目會給你一個執行在遠端伺服器上的python指令碼和伺服器地址,你需要分析指令碼存在的漏洞,確定攻擊演算法,然後編寫指令碼與伺服器互動,得到flag

0x03 RSA的常見攻擊方法

看不懂的彆著急,直接跳過看後面的小白福利環節

當模數N過小時

RSA的非對稱體制是建立在大整數分解難題上的,所以最基本的攻擊方法就是當模數N過小時,我們可以寫個指令碼直接爆破他的因子,如

那麼靠爆破來分解大整數N,我們可以分解多大的呢?

2009年12月12日,編號為 RSA-768 (768bits,232 digits)數也被成功分解。—-百度百科

然而現在一般RSA在實際應用裡都是2048位的,在CTF中出現的也不會太小,一般是不可能讓你爆破分解的,都是要用到一些攻擊演算法的,下面我來介紹下這些演算法

分解大整數的一些演算法

如果說N小了容易被分解,那麼N越大就越安全嗎?不然,RSA金鑰的安全不只和模數N有關,與它的指數:e和d也息息相關

這裡假設我們從題目獲得了公鑰(N,e)和待解密的密文c,由RSA的加解密過程,我們知道,如果要解密密文,我們要得到e的模反數d,而d是要我們去求解的。

這裡討論我們如何知道什麼時候該用什麼演算法,不進行數學證明及原理分析。下面我例舉其中幾個比較常見且容易理解的,因為作為最後的小白福利,我已經把這些演算法都整合進去了,感興趣的可以檢視原始碼

Wiener’s attack

https://en.wikipedia.org/wiki/Wiener%27s_attack

當 d < (1/3) N^(1/4)時,我們可以通過Wiener’s attack分解得到d

費馬分解

當大整數N的兩個因子p和q相近時,我們可以通過費馬分解的辦法很快分解大整數

Small q

當q較小時,即|p-q|較大時,我們可以直接爆破因子

Boneh Durfee Method

當d滿足 d ≤ N^0.292 時,我們可以利用該方法分解N,理論上比wiener attack要強一些。

yafu

yafu使用最強大的現代演算法去自動化的分解輸入的整數。大多數的演算法都實現了多執行緒,讓yafu能充分利用多核處理器(演算法包括 SNFS, GNFS, SIQS, 和 ECM)。

factordb

如果對一個大整數用一些特殊演算法也分解不了的時候,我們可以在 http://factordb.com/ 中查詢一下資料庫,說不定就能找到其因子

其他一些題型

有些題會給你一些隨機生成的大整數,一般來說是無法直接分解的,不過一般會給我們其他切入點

Rabin演算法

當e等於2時

小公鑰指數攻擊

當e十分小時,比如e等於3時

d洩露攻擊

如果我們知道一組過期的(N,e1,d1)和一組由新的e2組成的公鑰及其加密的密文(N,e2,c),我們可以由(e1,d1)得到模數N的兩個因子p和q,再去算e2的模反數d2,去解密密文

共模攻擊

使用相同的模數 N 、不同的私鑰,加密同一明文訊息

模不互素

兩個公鑰的N不互素時

Known High Bits Factor Attack

我們知道模數N其中一個因子的高位元位時

Stereotyped messages

如果你知道明文中最重要的部分,您可以使用此方法找到訊息的其餘部分。

Basic Broadcast Attack

同一個加密指數e和不同且互素的模數N加密了同一個密文,併發送給了其他e個使用者

0x04 小白福利環節

上面有一堆讓人頭大的演算法,比如分解一個大整數可能就有十來種演算法,當然不是每個演算法都能成功分解我們題目給的大整數的,如果我們挨個嘗試,不僅浪費精力還浪費時間,等你找到正確的演算法,已經與一血,二血,三血無緣了。所以我們需要一個自動化的工具,來幫助我們嘗試可能的演算法,並恢復出私鑰或者解密密文。於是我就用幾天時間寫了這麼一款小工具。

專案地址

https://github.com/D001UM3/CTF-RSA-tool

環境依賴

安裝libnum

安裝gmpy2

參考原文:https://www.cnblogs.com/pcat/p/5746821.html

原文裡面有的版本過老,會安裝失敗,可以參考我的安裝過程:https://d001um3.github.io/2018/01/24/CTF-RSA-tool-install/

克隆倉庫,安裝依賴

安裝sagemath(可選)

安裝sagemath的以支援更多的演算法,提高解題成功率,嫌麻煩也可以不安裝

官網:http://www.sagemath.org

我的安裝過程:https://d001um3.github.io/2017/12/06/sage/

幾個解題例子(更多參考專案目錄下example.txt)

在大多數情況下,你只需要把題目給的資訊輸入給指令碼,指令碼就會自動完成剩下的工作如:

1:題目給了一個公鑰檔案和密文,直接用 --key-k 指定公鑰,用 —decrypt 指定密文檔案就行了

2:題目給了你如(N,e,c)的十進位制值,分別通過-N-e-c輸入就行了

3:上面那種情況,如果題目是把這些引數都寫入一個文字檔案,如txt中,直接用 --input-i 指定文字檔案就行了

具體的例子:

Wiener’s attack

python solve.py --verbose --private -i examples/wiener_attack.txt

或者通過命令列,只要指定對應引數就行了

python solve.py --verbose --private -N 460657813884289609896372056585544172485318117026246263899744329237492701820627219556007788200590119136173895989001382151536006853823326382892363143604314518686388786002989248800814861248595075326277099645338694977097459168530898776007293695728101976069423971696524237755227187061418202849911479124793990722597 -e 354611102441307572056572181827925899198345350228753730931089393275463916544456626894245415096107834465778409532373187125318554614722599301791528916212839368121066035541008808261534500586023652767712271625785204280964688004680328300124849680477105302519377370092578107827116821391826210972320377614967547827619

利用 factordb.com 分解大整數

python solve.py --verbose -k examples/jarvis_oj_mediumRSA/pubkey.pem --decrypt examples/jarvis_oj_mediumRSA/flag.enc

small q attack

python solve.py --verbose --private -k examples/small_q.pub

費馬分解(p&q相近時)

python solve.py --verbose --private -i examples/closed_p_q.txt

Common factor between ciphertext and modulus attack(密文與模數不互素)

python solve.py --verbose -k examples/common_factor.pub --decrypt examples/common_factor.cipher --private

small e

python solve.py --verbose -k examples/small_exponent.pub --decrypt examples/small_exponent.cipher

Rabin 演算法 (e == 2)

python solve.py --verbose -k examples/jarvis_oj_hardRSA/pubkey.pem --decrypt examples/jarvis_oj_hardRSA/flag.enc

Small fractions method when p/q is close to a small fraction

python solve.py --verbose -k examples/smallfraction.pub --private

Known High Bits Factor Attack

python solve.py --verbose --private -i examples/KnownHighBitsFactorAttack.txt

d洩漏攻擊

python solve.py --verbose --private -i examples/d_leak.txt

模不互素

python solve.py --verbose --private -i examples/share_factor.txt

共模攻擊

python solve.py --verbose --private -i examples/share_N.txt

Basic Broadcast Attack

python solve.py --verbose --private -i examples/Basic_Broadcast_Attack.txt

再列舉幾個實用的小功能

輸入N與e建立公鑰

python solve.py -g --createpub -N your_modulus -e your_public_exponent -o public.pem

檢視金鑰檔案

python solve.py -g --dumpkey --key examples/smallfraction.pub

將加密檔案轉為十進位制(方便寫入文字,配合-i需要)

python solve.py -g --enc2dec examples/jarvis_oj_hardRSA/flag.enc

下面來介紹下我寫這個工具的思路

這個工具如何工作

根據題目給的引數型別,自動判斷應該採用哪種攻擊方法,並嘗試得到私鑰或者明文,從而幫助CTFer快速拿到flag或解決其中的RSA考點

大體思路

判斷輸入

首先,識別使用者的輸入,可以是證書 pem 檔案,也可以通過命令列引數指定ne等變數的值,甚至可以通過命令列指定題目所給的txt檔案並自動識別裡面的變數

判斷攻擊演算法

根據取到的引數型別及數量,選取可能成功的方法並採用一定的優先順序逐個嘗試。

如大整數分解的題型:給了一個公鑰和一個加密的密文,我們需要先分解大整數N,然後得到私鑰再去解密。考點在於大整數分解,指令碼的關鍵程式碼在CTF-RSA-tool/lib/factor_N.py中的solve函式

選擇輸出

CTFer可以通過命令列選擇是輸出私鑰還是輸出解密後的密文,還是一起輸出,不過非 --input(文字文件自動識別攻擊) 的情況下,請至少選擇 --private(列印得到的私鑰) 或 --decrypt(解密一個加密的檔案) 或 --decrypt_int(解密一個十進位制數) 中的一個。

0x05.還是沒有得到flag

首先如果題型是大整數分解的話,你還可以嘗試使用其他工具如 yafu 來分解,如果還是不能分解,你就得再好好看看這題是不是另有切入點了。

其次,如果是一些你沒見過的題型的話,建議通過百度,谷歌,github搜一下,一般還是能搜到的類似的題目甚至原題的

最後,如果還是做不出來,先女裝一下再去做題,聽大佬們說有buff加成

0x06.寫在最後

1:大部分演算法都是參照網上,我只是做了下整合彙總,並儘量使其易懂易用,程式碼不精,大佬輕噴。 2:還有很多實用的演算法(有關 Coppersmith 的演算法和一些分解大整數的演算法)暫時沒有加進去,一是精力有限,二是能力有限,三是沒遇到相關題型,以後會不斷完善。 3:大佬們覺得好用的話,點個 star 收藏一下,也歡迎各位來 contribute 和提 issues