看雪.WiFi萬能鑰匙 CTF 2017第十題 點評及解題思路
看雪CTF 2017 比賽進行至第十題
截止至今天中午12點,第十題破解人數為 13 人!
防守方 hsadkhk 依然位居首位~,第十題作者位居第五位。
、
此題過後,風間仁依然處於第一位,lacoucou再次進入前十。
期待ing......
接下來我們來回顧一下第十題
看看 看雪評委和出題者是怎麼說的ヾ(๑╹◡╹)ノ"。
看雪評委 netwind 點評
此題是一道演算法為主的題目,需要攻方熟練掌握大數運算以及RSA演算法。要解此題,首先要列舉e,然後再根據e、d、n求得p、q。
作者簡介
看雪ID:海風月影
職業:老牌打醬油人員
聯絡方式:無
興趣愛好:逛逛論壇,吹吹牛
特長:忽悠
研究方向:人工智慧
看雪 CTF2017 第十題設計思路
參賽內容:Windows 64位系統 CrackMe
檔名:cm.exe
CRC32:13F73C04
MD5:31A4B4FF1ABFE9F0C9A11CF4E37C2B86
SHA-1:F38DE836BE531F436ACFD04100FFA52848FEFF15
設計思路
題目:RSA 密碼學演算法,窮舉 e,快速分解 N
cm 執行流程:
輸入全大寫 70 個字元,前 6 個,後 64 個,分別為兩個 16 進位制大數:e, p
e、p 都是質數(Miller Rabin 測試演算法)
初始化 N、D 兩個大數,N 為 512 位
N=6248BC3AB92A33B000FDB88568F19727F92F79EB68FF6AD73203EFD20A3E331BE94
1C7AA288095F33BC4B255FD983114D480EFFBEE2E313E6218A57F9CCC8189
D=2476A7F02588913F228923E1F36F963F29708C07B117396817A6B94C336FC77FF7D3
81925EB40CFED8FBE894570155E41569B4EC69B26CB0320105A29651CB4Bp == 0 (mod N),則設 q = N / p,p < q 驗證D = ( - 1)( - 1) 上面全通過,完畢。
解題思路
N 是 512 位,分解 N = pq,e = D ( - 1)( - 1),拼接 ep 完畢(如果是 768
以上的,目前就不能用這種方法了,為了放水。。。所以 N 設計成 512 位)
分解方法,使用 ggnfs 和 msieve 工具即可,這裡不多說了。2 天內分解完,可能有點難度。
下面選取攻擊者 lacoucou 的破解分析
1. PEID 掃描
又是大數運算,IDA開啟:
F5,好直觀:
查詢字串:
有 PEID 和上邊的字串資訊可知,是用GMP實現的大數運算,接著就是猜每個函式的意義了。
由 MPN 的官方文件可知:
1. 所有物件使用前要初始化,通過呼叫函式 mpz_init來完成
2. 一般的函式,第一個引數為輸出函式,後邊的為輸入引數
剛開始,使用的預設值來計算,進展緩慢,後來把mpn_set_str_140007990 處的大數改成0x10之後,進展飛快。
__int64 sub_140006F50() { signed __int64 v0; // rax@1 __int64 v1; // r8@4 __int64 v2; // rdx@4 char v3; // cl@5 char v4; // al@9 int v5; // eax@14 const char *v6; // rcx@14 char v8; // [sp+20h] [bp-18h]@12 printf_140006EA0( "=========================================================================\n" ); printf_140006EA0( " 看雪CTF2017 CrackMe by 海風月影\n\n" ); printf_140006EA0( " 請輸入序列號:" ); scanf_140006F00( "%s" , &g_dwInput_140051F20); printf_140006EA0(&unk_14004BF30); v0 = -1i64; do ++v0; while ( *((_BYTE *)&g_dwInput_140051F20 + v0) ); if ( (_DWORD)v0 == 70 ) { v1 = 0i64; v2 = 0i64; while ( 1 ) { v3 = *((_BYTE *)&g_dwInput_140051F20 + v2); // 大寫字母加數字 if ( (unsigned __int8 )(v3 - 48) > 9u && (unsigned __int8 )(v3 - 65) > 0x19u ) break ; if ( ++v2 >= 70 ) { dword_140052F98 = g_dwInput_140051F20; word_140052F9C = word_140051F24; do { v4 = *((_BYTE *)&g_dwInput_140051F20 + v1 + 6); byte_140052F30[v1++] = v4; } while ( v4 ); // 初始化 mpn_set_str_140007990(&mpn_str_left_6_140051F10, &dword_140052F98, 16i64); mpn_set_str_140007990(&mpn_str_right_64_140052F20, byte_140052F30, 16i64); // 判斷是否為質數 if ( mpz_probab_prime_p_140007350(( __int64 )&mpn_str_right_64_140052F20, 500u) ) { if ( mpz_probab_prime_p_140007350(( __int64 )&mpn_str_left_6_140051F10, 500u) ) { // 初始化 mpz_set_si_140007AD0(&unk_140051EF0, 0i64); mpn_set_str_140007990( &big_1, "6248BC3AB92A33B000FDB88568F19727F92F79EB68FF6AD73203EFD20A3E331BE941C7AA288095F33BC4B255FD983114D480EFFBEE" "2E313E6218A57F9CCC8189" , 16i64); mpn_set_str_140007990( &big_2, "2476A7F02588913F228923E1F36F963F29708C07B117396817A6B94C336FC77FF7D381925EB40CFED8FBE894570155E41569B4EC69" "B26CB0320105A29651CB4B" , |
完整函式如上,流程如下:
1.假設輸入的字串為szInput
2.首先判斷szInput的長度是否為70個位元組
1 2 3 4 5 | v0 = -1i64; do ++v0; while ( *((_BYTE *)&g_dwInput_140051F20 + v0) ); if ( (_DWORD)v0 == 70 ) |
3.接著判斷這些字元是否由 0-9 和A-Z的字元組成:
1 2 3 4 | v3 = *((_BYTE *)&g_dwInput_140051F20 + v2); // 大寫字母加數字 if ( (unsigned __int8 )(v3 - 48) > 9u && (unsigned __int8 )(v3 - 65) > 0x19u ) break ; |
4.將輸入字串分成兩段,第一段為原字串的0-6自己,第二段為後64位元組
dword_140052F98 = g_dwInput_140051F20; word_140052F9C = word_140051F24; do { v4 = *((_BYTE *)&g_dwInput_140051F20 + v1 + 6); byte_140052F30[v1++] = v4; } while ( v4 ); |
5.用這兩個字串來初始化兩個mpz結構題:
1 2 3 | // 初始化 mpn_set_str_140007990(&mpn_str_left_6_140051F10, &dword_140052F98, 16i64); mpn_set_str_140007990(&mpn_str_right_64_140052F20, byte_140052F30, 16i64); |
結構體定義:
1 2 3 4 5 6 7 | typedef unsigned long mp_limb_t struct __mpz_struct { int _mp_alloc; //申請的大小 _mp_alloc=申請位元組數/8 int _mp_size; //當前佔用的大小 _mp_size=使用位元組數/8 mp_limb_t * _mp_d; //資料指標 }; |
初始化前6個字元的例子:
記憶體中,rcx地址的值:
執行之後:
6. 判斷是否為素數
1 2 3 | if ( mpz_probab_prime_p_140007350(( __int64 )&mpn_str_right_64_140052F20, 500u) ) { if ( mpz_probab_prime_p_140007350(( __int64 )&mpn_str_left_6_140051F10, 500u) ) |
這裡花了點時間,後來通過連續測試0-0x10基本可以確定是判斷素數。
跟官方文件似乎不太一樣。
7. 初始化幾個值
// 初始化 mpz_set_si_140007AD0(&unk_140051EF0, 0i64); mpn_set_str_140007990( &big_1, "6248BC3AB92A33B000FDB88568F19727F92F79EB68FF6AD73203EFD20A3E331BE941C7AA288095F33BC4B255FD983114D480EFFBEE" "2E313E6218A57F9CCC8189" , 16i64); mpn_set_str_140007990( &big_2, "2476A7F02588913F228923E1F36F963F29708C07B117396817A6B94C336FC77FF7D381925EB40CFED8FBE894570155E41569B4EC69" "B26CB0320105A29651CB4B" , 16i64); mpz_set_si_140007AD0(&v8, 0i64); |
8.用大數0x62..... 模上我們輸入的64位然後與0比較:
1 2 | mpz_mod_140007B10(( __int64 )&v8, ( __int64 )&big_1, ( __int64 )&mpn_str_right_64_140052F20); if ( !mpz_cmp_si_1400075D0(&v8, 0i64) ) |
9.用大數0x62..... 除以我們輸入的64位然後與商做比較,商大於我們輸入的數:
1 2 | mpz_div_1400071E0(&unk_140051EF0, &big_1, &mpn_str_right_64_140052F20); if ( mpz_cmp_140007560(&mpn_str_right_64_140052F20, &unk_140051EF0) <= 0 ) |
10.最後一段,p=input[6:64] 商q=big_1/p v8=(p-1)(q-1)
mpn_sub_1400079F0(&mpn_str_right_64_140052F20, &mpn_str_right_64_140052F20, 1i64); mpn_sub_1400079F0(&unk_140051EF0, &unk_140051EF0, 1i64); mpn_mul_140007610(&v8, &mpn_str_right_64_140052F20, &unk_140051EF0); // 猜不出來 sub_1400073B0(( __int64 )&v8, ( __int64 )&mpn_str_left_6_140051F10, ( __int64 )&v8); v5 = mpz_cmp_140007560(&big_2, &v8); v6 = "註冊成功!!!\n\n" ; if ( !v5 ) goto LABEL_16; |
有了以上資訊,結合上一題的坑,基本猜到是RSA,不然還能有啥。。。。。。。。
RSA 演算法:
RSA金鑰生成步驟:
根據以上資訊,以及計算過程:
1 2 3 4 5 6 7 8 | mpz_mod_140007B10(( __int64 )&v8, ( __int64 )&big_1, ( __int64 )&mpn_str_right_64_140052F20); if ( !mpz_cmp_si_1400075D0(&v8, 0i64) ) mpz_div_1400071E0(&unk_140051EF0, &big_1, &mpn_str_right_64_140052F20); if ( mpz_cmp_140007560(&mpn_str_right_64_140052F20, &unk_140051EF0) <= 0 ) { mpn_sub_1400079F0(&mpn_str_right_64_140052F20, &mpn_str_right_64_140052F20, 1i64); mpn_sub_1400079F0(&unk_140051EF0, &unk_140051EF0, 1i64); mpn_mul_140007610(&v8, &mpn_str_right_64_140052F20, &unk_140051EF0); |
猜測:
1 2 3 4 | big_1即為N big_2可能是D N=0x6248BC3AB92A33B000FDB88568F19727F92F79EB68FF6AD73203EFD20A3E331BE941C7AA288095F33BC4B255FD983114D480EFFBEE2E313E6218A57F9CCC8189L D=0x2476A7F02588913F228923E1F36F963F29708C07B117396817A6B94C336FC77FF7D381925EB40CFED8FBE894570155E41569B4EC69B26CB0320105A29651CB4B |
線上分解N,達到P,Q:
可知:
1 2 | p =64111581030502014729907148975807553274150008894301323553363399183151805372611 q =80290597658186981463023471970341877717671071586519890660723213036500314978243 |
把P轉成十六進位制作為後64位,果然可以直接執行到:
1 2 3 | // 猜不出來 sub_1400073B0(( __int64 )&v8, ( __int64 )&mpn_str_left_6_140051F10, ( __int64 )&v8); v5 = mpz_cmp_140007560(&big_2, &v8); |
那麼肯定是要根據以下公式求解E
1 2 3 4 5 | ed - 1 = kφ(n) e:不知道,待求 d:私鑰,似乎是big_2 0x 2476..... K:為整數 φ(n)=(p-1)*(q-1) |
根據以上條件,寫python,計算:
1 2 3 4 5 6 7 8 9 | def calc_e() ola_n = (p - 1 ) * (q - 1 for x in range ( 1 , 10000000 ): e = (ola_n * x + 1 ) / big_num_2 if ola_n * x + 1 = = big_num_2 * e: #驗證e是否為整數(是否捨棄了小數部分 10/3=3 3×3!=10) print e, hex (e) 輸出: 16077491 0xf552b3L |
完整註冊碼:
F552B38DBDDE72E2E693B2AED5C769C0DCB3DA83534480A80E652FFE53544CD91A18C3
最後感謝 WiFi 萬能鑰匙安全應急響應中心的贊助支援,
接下來的比賽大家一定要使出洪荒之力哦!↖(^ω^)↗
比心 ❤
上海連尚網路科技有限公司成立於 2013 年,是一家專注於提供免費上網和內容服務的移動網際網路企業。連尚網路自主研發的核心產品 WiFi 萬能鑰匙,以分享經濟的模式,通過雲端計算和大資料技術,利用熱點主人分享的閒置WiFi資源,為使用者提供免費、穩定、安全的上網服務,以幫助更多的人上網,找到屬於他們的機會,改變自己的命運。
相關文章
- 看雪.紐盾 KCTF 2019 Q3 | 第十題點評及解題思路2019-10-08
- 看雪.紐盾 KCTF 2019 Q2 | 第十題點評及解題思路2019-07-05
- 看雪.紐盾 KCTF 2019 Q3 | 第十一題點評及解題思路2019-10-08
- 看雪.紐盾 KCTF 2019 Q3 | 第十二題點評及解題思路2019-10-08
- 看雪.紐盾 KCTF 2019 Q3 | 第十三題點評及解題思路2019-10-08
- 萬能wifi鑰匙2020-12-24WiFi
- 看雪CTF.TSRC 2018 團隊賽 第十題『俠義雙雄』 解題思路2018-12-21
- 看雪CTF.TSRC 2018 團隊賽 第十一題『伊甸園』 解題思路2018-12-23
- 看雪.紐盾 KCTF 2019 Q3 | 第四題點評及解題思路2019-09-29
- 看雪.紐盾 KCTF 2019 Q3 | 第七題點評及解題思路2019-09-30
- 看雪.紐盾 KCTF 2019 Q3 | 第一題點評及解題思路2019-09-25
- 看雪.紐盾 KCTF 2019 Q3 | 第六題點評及解題思路2019-10-08
- 看雪.紐盾 KCTF 2019 Q3 | 第八題點評及解題思路2019-10-08
- 看雪.紐盾 KCTF 2019 Q3 | 第九題點評及解題思路2019-10-08
- 看雪.紐盾 KCTF 2019 Q2 | 第七題點評及解題思路2019-07-02
- 看雪.紐盾 KCTF 2019 Q2 | 第九題點評及解題思路2019-07-04
- 看雪.紐盾 KCTF 2019 Q2 | 第六題點評及解題思路2019-07-01
- 看雪.紐盾 KCTF 2019 Q2 | 第八題點評及解題思路2019-07-03
- 看雪.紐盾 KCTF 2019 Q2 | 第一題點評及解題思路2019-07-01
- 看雪.紐盾 KCTF 2019 Q2 | 第二題點評及解題思路2019-07-01
- 看雪.紐盾 KCTF 2019 Q2 | 第三題點評及解題思路2019-07-01
- 看雪.紐盾 KCTF 2019 Q2 | 第五題點評及解題思路2019-07-01
- 看雪CTF.TSRC 2018 團隊賽 第十四題『 你眼中的世界』 解題思路2018-12-29
- 看雪CTF.TSRC 2018 團隊賽 第十五題『 密碼風雲』 解題思路2019-01-02密碼
- 看雪CTF.TSRC 2018 團隊賽 第十二題『移動迷宮』 解題思路2018-12-25
- 看雪CTF.TSRC 2018 團隊賽 第十三題『 機器人歷險記』 解題思路2018-12-27機器人
- 看雪CTF.TSRC 2018 團隊賽 第九題『諜戰』 解題思路2018-12-19
- 看雪CTF.TSRC 2018 團隊賽 第七題 『魔法森林』 解題思路2018-12-23
- WiFi萬能鑰匙蹭網原理詳細剖析2020-08-19WiFi
- 看雪CTF.TSRC 2018 團隊賽 第一題 『初世紀』 解題思路2018-12-23
- 看雪CTF.TSRC 2018 團隊賽 第二題 『半加器』 解題思路2018-12-23
- 看雪CTF.TSRC 2018 團隊賽 第五題 『交響曲』 解題思路2018-12-23
- 看雪CTF.TSRC 2018 團隊賽 第六題 『追凶者也』 解題思路2018-12-23
- 看雪CTF.TSRC 2018 團隊賽 第八題 『二向箔』 解題思路2018-12-23
- [原創]看雪CTF2017第二題lelfeiCM的writeup2019-02-25TF2
- 看雪CTF.TSRC 2018 團隊賽 第三題 『七十二疑冢』 解題思路2018-12-23
- 看雪CTF.TSRC 2018 團隊賽 第四題 『盜夢空間』 解題思路2018-12-23
- 看雪·眾安 2021 KCTF 秋季賽 | 第十題設計思路及解析2021-12-16
- 看雪·深信服 2021 KCTF 春季賽 | 第十題設計思路及解析2021-05-31