kitctf 中的 crypto 題目
One Trick Pony
題目
I know a few secrets about this KAsino. But they would not be secrets if a shared them with everybody, so of course I do not share them in plaintext. Good luck getting past my information-theoretic secure encryption.
This challenge is the first from a set of two challenges.
nc kitctf.me 12345
附件
|
解題思路
nc kitctf.me 12345 之後,拿到以下字串。
33AE0C532293259809A0DBC89A928D235CAB3AD86F8082AD15355C0D56EDE9F207412DC64431D73F053B6461379B3FB6C7D7EDA9FFD0273F2ED61C28521DB1EE17814A8124808E091E7811E2CAAF04FBEA183F4285C048DB46C01C279879A928226D973793C08A71B87D979D76544CE119BCE109BD8F39E4DDEA3CF1EEDFAEC036DC937D |
看似已經沒有其他東西了,但在使用rand();的情況下,我在gcc中測試發現不論版本每次運行中輸出的值都一樣,所以也可以拿到一串字串。
|
0x67C6697351FF4AEC29CDBAABF2FBE3467CC254F81BE8E78D765A2E63339FC99A66320DB73158A35A255D051758E95ED4ABB2CDC69BB454110E827441213DDC8770E93EA141E1FC673E017E97EADC6B968F385C2AECB03BFB32AF3C54EC18DB5C021AFE43FBFAAA3AFB29D1E6053C7C9475D8BE6189F95CBBA8990F95B1EBF1B305EFF700 |
最終就很簡單了,依照 One-time pad 的特性。
解答
from Crypto.Util.number import long_to_bytes |
Crooked Roulette
題目
Your Seatmate is sure to know what you have to bet in the next Round of K-Roulette™. But he does not have the guts to bet it himself. Can you make the bet and win it all?
nc kitctf.me 4545
附件
#!/usr/bin/env python3 |
解題思路
這題是我很喜歡的一題,本來弄了一堆做法想要靠數學解都弄不出來,後來想說是不是我想得太複雜了,就慢慢看題目,突然想到應該是可以透過sign(m)這個方程來幫我算解答的。
後來也證實這題雖然看起來像RSA,但核心完全不一樣。
但直接代入題目顯示的result,會進到下面此行,從而不能取得flag。
if m2 % n == result: |
後來我突然想到一個很漂亮的方法,把 n - result 塞進去,拉出來的 sign * -1 + n,就可以還原出真正的 sign,數學上的等價我就不證明了,大致等價於以下。
連上nc kitctf.me 4545之後,得到以下資訊。
Number of pockets: 0x86d14a294d4ecd523e982ab61b40e716b8a78ef12ce3e3367cc29396c45963a0c509c813159e7fa5418dca1e1ec5014e9653448b54ba6daa5aef6314f0d88cc16c5fca79a119b3766319f3e182d817acce98b4b4c296ca89827a8de5c7b91e0570f6abaec565224c6d8f0d93f0b32acc9f34bbb27216249517291bb0b3cd8f7f |
解答
基本上照著1、2、3的順序填就好。
n = 0x86d14a294d4ecd523e982ab61b40e716b8a78ef12ce3e3367cc29396c45963a0c509c813159e7fa5418dca1e1ec5014e9653448b54ba6daa5aef6314f0d88cc16c5fca79a119b3766319f3e182d817acce98b4b4c296ca89827a8de5c7b91e0570f6abaec565224c6d8f0d93f0b32acc9f34bbb27216249517291bb0b3cd8f7f |
Optimal Technology Project (未解決)
題目
There are some more secrets. Again, this one is encrypted. And I did not make the same mistake as last time. And I heard everything would be better in rust, so I will use that now.
This challenge is the second from a set of two challenges. (Due to problems with the third challenge, it won’t be released)
附件
use rand::{Rng, SeedableRng}; |
解題思路
這題跟 One Trick Pony 很像,本來以為可以爆開的,但 rust 的 rand 在未定義時,會自動代入 seed = 1970 年以來到現在的毫秒數。
我後來想到 nc 拿到密文之後,再往前倒推窮舉硬猜系統當下時間,但不知道為什麼失敗了。
Prime Guesser 1
題目
The Prime Guesser 9000 is a simple game: Guess the prime and win it all. Due to quantum computers, we encrypted the number before handing it to you. Luckily you installed the smartEncrypt™ on your smartphone to encrypt numbers yourself. Win 100 Rounds to receive the big jackpot!
nc kitctf.me 4646
附件
#!/usr/bin/env python3 |
解題思路
賽中看到檔案太長了,有點被繞暈就沒細看,星期天我就跑去找林妤瑄了,現在來補題消業障哇哇,還好系統都還開著
在重新做題的過程中,有參考 https://github.com/JoshuaTurner3/kitctfctf_2022,感謝他在我迷茫的時候給我了很多很多的思路。
實際運行起來的樣子如下。
725604,61748,736872,167264,726582,230045,684241,402364,500164,378821,676833,385962,883217,283011,821625,140155,818496,211240,1004947,476860,795144,628346,262435,659908,531596,453064,997759,725680,363241,37811,19872,2529,695247,348406,34052,930284,737477,690703,307210,155771,891828,214473,421622,962674,114283,878362,209636,158230,724381,10328,63827,815739,480336,540171,486032,507201,775681,388709,359443,853874,683789,506695,644574,119382 |
這裡在程式中的這個迴圈內。
while True: |
他的意思大概是這樣,輸入0時,可以給server一個1-20的數字加密,數字被加密後,會再全部輸出出來,大概長下面這樣。
What do you want? |
輸入1的時候,要輸入兩串list給server,server會跑解密程式來比對兩串list解密出來的值是否為0,我丟輸入0時取得的密文,可想而知的失敗了,果然事情沒那麼簡單。
What do you want? |
輸入2時,會跳出迴圈,進入以下程式碼。
real_factors = get_factors(number) |
大概就是要連續猜對隨機生成數字的質數100次,在過程中可以一直重複跑0跟1來蒐集資訊。
接下來來看解密函數。
def polyadd(x, y, modulus, poly_mod): |
整個程式太過複雜了,但幸運的是解密函數真正用到的東西並不多,並且只有解密的部分,不需要猜測種子等等東西,不過還是有一些全域變數影響解密。
# polynomial modulus degree |
然後就幹,輸光,去床上躺一下再說。
def keygen(size, modulus, poly_mod): |
接下來開始算初始值。
poly_mod = np.array([1] + [0] * (arrSize - 1) + [1]) |
q, t, sk 我是從這裡找到求解函數的。
接下來就可以在本地端從一開始給出的密碼開始算,然後我發現我Kubeflow還沒弄,先這樣哇哇,後續就是推算初始值和算完100輪他要什麼,但老實說這題我的能力不夠,在來一次賽中也解不出來,不過學到很多東西。