20210710-CTFSHOW CJB-CryptoSecPartWriteUp
Cop! Run!!
la佬出的题目
题目描述
1 | from Crypto.Util.number import * |
hint
1 | Brad Pitt & Angelina Jolie love each other hard in some movie. |
解题思路
题目中出现Cop,猜测是CopperSmith;从hint中获悉,一部零五年的电影《Mr Smith & Mrs Smith》,是CopperSmith没跑了
先看代码,代码很简短,显然只要求出 x 的前两项,所有的问题就迎刃而解,或者说,只要知道 x[1] ,就可以求出 y ,然后依据异或的性质,加密即解密
而我们已知的是 x 右移73位的数据,显然是要求低位。自然而然可以想到方程的思想,设置几个变量,然后根据等式解方程。因为前面接触过 CopperSmith 在 RSA 中的应用,sage 里的 smal_roots 就是基于 CopperSmith 实现的
下面简单介绍一下 CopperSmith ,摘自CTF Wiki
CopperSmith基本原理
Coppersmith 相关攻击与 Don Coppersmith 紧密相关,他提出了一种针对于模多项式(单变量,二元变量,甚至多元变量)找所有小整数根的多项式时间的方法。
这里我们以单变量为主进行介绍,假设
- 模数为 N ,N 具有一个因子$b≥N^β,0<β≤1$
- 多项式 F 的次数为$δ$
那么该方法可以在$O(cδ^5log^9(N))$的复杂度内找到该多项式所有的根$x_0$,这里我们要求 $|x_0|<cN^\frac{β^2}{δ}$。
在这个问题中,我们的目标是找到在模 N 意义下多项式所有的根,这一问题被认为是复杂的。Coppersmith method 主要是通过 Lenstra–Lenstra–Lovász lattice basis reduction algorithm(LLL)方法找到
- 与该多项式具有相同根 $x_0$
- 更小系数
- 定义域为整数域
的多项式 g,由于在整数域上找多项式的根是简单的(Berlekamp–Zassenhaus),从而我们就得到了原多项式在模意义下的整数根。
那么问题的关键就是如何将 f 转换到 g 呢?Howgrave-Graham 给出了一种思路
也就是说我们需要找到一个具有 “更小系数” 的多项式 g,也就是下面的转换方式
在 LLL 算法中,有两点是非常有用的
- 只对原来的基向量进行整数线性变换,这可以使得我们在得到 g 时,仍然以原来的 $x_0$ 为根。
- 生成的新的基向量的模长是有界的,这可以使得我们利用 Howgrave-Graham 定理。
在这样的基础之上,我们再构造出多项式族 g 就可以了。
关于更加细节的内容,请自行搜索。同时这部分内容也会不断更新。
需要注意的是,由于 Coppersmith 根的约束,在 RSA 中的应用时,往往只适用于 e 较小的情况。
总结,CopperSmith 可以用来一元甚至多元的多项式
回到题目,初步尝试,在尚师傅的指导下,我写出来了第一个多项式,设 $x_{0}$ 的低73位为 k
$$
f(x_{0}<<73+k)>>73=x_{1}\notag
$$
是关于 k 的一元多项式,然后我们尝试能不能解
la佬的博客上有解一元和多元的脚本
1 | #Sage |
改了一下
1 | p = 92946459607669937513774102250057295249718593723232674702212854287358873135783 |
有几个问题,首先这样向右位移不知道中不中,然后总是报越界的错
在尝试以及一些等效替代无果后,我想到再添加一个变量;一是因为这样表示更加清晰,省去了向右位移的不确定性,二是la佬的博客里,也有求解多元多项式的脚本
设 x[0] x[1] 的低73位为 k0 和 k1,写出来的等式是
$$
f(x_{0}<<73+k_0)=x_{1}<<73+k_1\notag
$$
然后找到了原题
是三个月前 zer0pts CTF 的题目,找到了 Joseph 师傅的博客,参考zer0pts CTF 2021 - Crypto-easy pseudo random
然后当时就是改了他的脚本做出来的,除了一些推导,还提供了一个 coppersmith 求小根函数的 github 链接,https://github.com/defund/coppersmith/
1 | import itertools |
稍微改一下脚本就出来了
1 | load('coppersmith.sage') |
将这个函数用到我昨天的等式上,发现也可以出来
1 | load("coppersmith.sage") |
海那边漂来的漂流瓶
春哥师傅的题目
题目描述
在海的那边漂过来一个漂流瓶,停在了沙滩上。 你把它捡起来,却不知道漂流瓶里的纸上到底写了些啥。
1 | ZJ6 -3 AI6 G8 EL NJ4 EJ/ XJ4 1O3 FU3 RU RUP EJ/ XJ4 S06 54 284 Q/6 J0 , 5J3 VU04 T;6 2J4 431 EJ/ XU3 。 Y4 1O3 D9 G3 S06 VU/6 , U VM4 RU/ EJI4 RU XJ/6 G4 、 VUP 1O3 G4 、 W96 1O3 G4 、 WL6 M06 G4 、 VUP 5J6 VU04 、 VUP 5J6 G4 、 AUL6 XU4 VU04 、 W96 5J/ G4 、 5; CJ84 VU04 、 S06 W.6 VU04 、 MP6 XUP6 VU04 、 RU8 U4 VU04 、 RU8 U4 G4 、 W96 S06 G4 、 EL VM/6 G4 、 QU/6 2J/ VU04 。 ZJ6 X94 EK6 2U6 SO4 BJ/6 G4 T QJ6 WL6 1J4 WJ3 QJ6 WL6 QU6 1J4 T QJ6 WL6 2L3 WJ3 QJ6 WL6 QU6 2U6 C04 M3 QUP UP G.3 Y4 AJ3 QUP RU, 。 FU6 5J/ U.6 M6 XJ4 2J04 RU04 GK4 G6 2U6 M/4 2U4 FM3 2K6 JP4 WU6 , Y94 W96 5J/ G4 M3 5; CJ84 VU04 5 RU0 M06 1P3 U/ E9 G4 S06 1O3 Y.3 VU;4 2U6 ZJ6 -3 AI6 G8 EL NJ4 EJ/ XJ4 CP3 XU4 J94 2U4 G4 T/6 VU04 2J/ VU VU;4 2U6 Y.3 VU;4 , Y4 S06 1J4 1O3 G;4 VU0 RU/ 5; CJ84 VU04 ZP M06 VU; , DJ84 J VU 54 W96 5J/ G4 J4 Z/ FM 、 J B4 FM 5 C.4 , Y94 VU;4 VU VU/6 54 5; CJ84 VU04 1O3 1J4 2U6 5; CJ84 G4 , U06 J VU ( NJ6 T/ 284 2J4 VU ) VU VU/6 54 5; CJ84 VU04 CK6 AO3 5P4 , 5J03 EK4 RU, RUP4 56 RUL3 2U6 284 J0 , DJ84 M,4 284 2J4 VU RUP4 BJ4 W96 5J/ G4 C93 VU04 2U4 FM 。 1U,6 J;4 RU4 183 ZJ6 X94 EK6 M/4 VU WU 94 ZJ3 VU.4 2U6 EK6 G4 1L EJI3 FU3 X96 I6 。 VU; 2JO4 M6 5J/ G0 EL 2; TJ EJO CJ86 G4 U3 TJ04 XU06 W96 J0 VU 04 5J3 UL4 284 T/6 G4 JO6 AJ4 2U6 , DL3 XU;6 2L4 QU/6 C/6 2U4 FM Z8 503 、 WJ3 2U4 FM3 2K6 2U6 T/6 1P3 M3 1U4 AU03 2J G4 ZJ4 RUP4 2J03 WJ6 WJ/ FUP6 TK XU.6 YL4 T/6 YJ3 N9 , ZJ6 -3 AI6 G8 EL NJ4 EJ/ XJ4 2U6 VM03 VU04 RU, DK4 U4 1U4 D9 1J4 ZP BP6 D.3 T.6 AU4 2U6 2J CJO4 FM 1U/4 RU/ EJI4 VM3 2JI M06 1P3 2U 2J4 D9 Z8 2U6 VU; HJP 2U4 294 。 |
hint1
1 | 广州火车站上霸气外露的标语:统一祖国 振兴中华 |
hint2
1 | 靠北耶!E04! |
解题思路
显然是类似一种单表替换的东西,然后随便挑了几个去搜,就在 github 上找到https://github.com/chinese-opendesktop/cin-tables/blob/master/bopomofo.cin 至于第一个 hint 我到现在都没有理解其意思,第二个 hint 是台湾方言和台湾网络用语
github 里是正体注音輸入法的对照词库吧,正好对应了 E04! 的由来,也很呼应题目
手撕了
1 | 福尔摩沙高速公路北起基金公路南至大鹏湾,主线长431公里,自北开始南行,依序经过基隆市、台北县、桃园县、新竹县、苗栗县、台中县、彰化县、南投县、云林县、嘉义县、台南县、高雄县与屏东县。fu lai ge的内容是吃葡萄不吐葡萄皮不吃葡萄不吐葡萄皮的汉语拼音首字母拼接。 |
然后看官方 WP 春哥师傅说可以用在线的网站搞;切换下输入法就好
群主说要出简单的题目大家把这题想简单一点
1 | N = 24873777989291448485268365702265085243886872900039809831478881276969311714448924581398692832639705916538111455861057354225427758736198452679468399039512440497290615485190994957684665065261280544484301856860844163436499302230085760545686486398949018187416289923500558688885485672960734334858119391323987554701544773420070317895909846297195832399677291338220818181502181317849952785959097285626009703863257450199781708945715701136683994546852422993684382468187651935055302074609980311161155531603473091857526099148935429447319415714778860215376802270686310782735079899235228731429165106477537031235405221734008734614847 |
e 很大,尝试过 boneh_durfee,但是出不来;检查条件,这 e 也太大了吧
然后在诸多hint中看到
当你凝视密文的时候,密文也在凝视着你
哈哈
当你凝视密文的时候,明文也在凝视着你
The Dedication of Suspect M
8神师傅的题目,春哥师傅隔了7分钟就出了并且全场唯一解,直到比赛结束,我都丝毫没有头绪
题目描述
题目信息很多
解题思路
我整理出来的,有以下线索:
是一个动态的环境,提供压缩包下载,里面有个名为 M 的二进制文件,文件内容每重开一次环境都不相同、大小从 2K 到 5K 不等;那么flag 基本上也是动态的了
flag 的内容是小写字母的十六进制,中间有短横分隔
嫌疑人X的献身改成了嫌疑人M的陷深
根据现有的线索:动态的每次 flag 都不相同、0-9 a-f,我所能想到的就是
但我和组内的师傅试过,不管是给文件 md5,还是给压缩包 md5,都不太行
春哥的思路是将那些不可见的字符给转变成换行符0D 0A
,也就是\r \n
,windows用\r\n
表示换行
就是将这些不可见的小点通过在128个ascii字符表中位移带走
春哥师傅准确计算出了密钥,我第一次也可以,但怎么改那些小字母数字提交的flag都不对,之后我重新开了几次环境,就直接爆破了
1 | with open('../M', 'rb') as f: |
找到像样的,是figlet艺术字,手敲一遍
比赛结束,刷了几道CTFSHOW上的题,记录一下
36D杯
justShow
1 | hlcgoyfsjqknyifnpd:bcdefghijklmnopqrstuvwxyza |
冒号后面的提示凯撒位移,移回来得到
1 | gkbfnxeripjmxhemoc:abcdefghijklmnopqrstuvwxyz |
然后没想到是playfair,后面是key;拿去在线网站解密一下
这里有点狗,因为playfair的字母表只有25个,一般是用i代替j;但这里不是,还没有明说,所以缺省情况是出不来的。因为key就是a-z,所以字母表就是a-z,不用代替任何字母了,随便改一下参数
得到flag
1 | flagctfshow{ctfshowicome} |
飞鸽传书
提供附件下载,pub.key
1 | TVdJd09HRm1NamMyWkdKak56VTVNekkzTVdZMFpXVTJNVFl5T0Rrek1qUWxNRUZsTW1GbE0yRXlNelV3TnpRell6VXhObU5rWVRReE1qUTVPV0poTTJKbE9TVXdRV0prWlRVeVkySXpNV1JsTXpObE5EWXlORFZsTURWbVltUmlaRFptWWpJMEpUQkJaVEl6WlRBd1ltVXpPV1F6Tm1Zek5EWXlaVFUzTm1FMk4yRTNaamt4T1RrbE1FRXhPR00zT1RJNE5XSTFNVFJqTmpObVl6a3dNelZsTTJZNU1qQmhaVFEzTnlVd1FXUmhORFJrWkRFNU1tUmxabVF4WW1VM09XWTJNMk16TlRCa01qa3lNR05tSlRCQk5ESTFNV00wWXpZME9XTTNaREptT0RZek1qZGxabVJsTWpNNU9USm1ZVGNsTUVGaFlXVTNZakprTkRneU16Z3lZV0ZoWkRjMVptUmxOalJrWmpobVpqZzJaaVV3UVRJNU5tWTNabVpqTW1VME5UUTFaR00zTnpreU1EVXdZMlZpTkdFNE56RXhKVEJCTmpFd04yRmpNV0UxTldZeFpUQm1aV05pTjJSa1lqWXdabUl6WW1ZeE1Ea2xNRUZoWldNeU16TXpNekl4WkRjek1EQXdNVFl4TmpneVpETmpOR1ZpWXpBd09TVXdRVFV3TURWaU0ySm1NREF3TlRCaVpqUm1OMlUwTTJGak16TmhNRFExTkdJNEpUQkI= |
不是很正规的PEM格式的公钥文件,尝试手撕,两次Base64,一次URL,得到
1 | 1b08af276dbc7593271f4ee616289324 |
看着有点像MTP,跑一下美团用过的脚本,出来这样一个玩意,没有任何实际意思可言,麻了
然后看了wp是hash函数类型的,然后找逆hash的网站,有些网站要登录收费了;解成功的几个发现是md4,且结果有数字和字母,于是自己写个爆破一下
记得hashlib库里好像没有md4,就从github上随便找了一段源码
1 | def _pad(msg): |
exp
1 | from sage import MD4 |
得到flag
1 | flag{36D_me} |
以后md4不愁了,此外md4也是32位的
BJDCTF
编码与调制
题目描述
1 | 密文:2559659965656A9A65656996696965A6695669A9695A699569666A5A6A6569666A59695A69AA696569666AA6 |
hint
解题思路
计网的知识,曼切斯特和差分曼切斯特
- 标准曼切斯特:低到高 0,高到底 1
- IEEE曼切斯特:刚好相反,低到高 1,高到底 0
- 差分曼切斯特:前后相同为 0,不同为 1
- 其他类型:只有5,6,9,a这此种字符的
- 注意:存在字节逆序的问题:每8个字节一逆序
老早就在la佬的博客看到,曼切斯特编码的脚本,这次终于用上了,收收好
显然密文中只出现了569a这几个字符,在其他解法这里
这里是省略第一位的,不排除有其他变式,备份一下脚本
1 | #!/usr/bin/env python |
Polybius
1 | 密文:ouauuuoooeeaaiaeauieuooeeiea hint:VGhlIGxlbmd0aCBvZiB0aGlzIHBsYWludGV4dDogMTQ= |
hint解出来
1 | The length of this plaintext: 14 |
密文全部是由5个元音字母组成,明文的长度是密文的一半,题目提示是是波利比奥斯棋盘密码,没有说密钥
所谓的波利比奥斯棋盘密码,和 playfair 同属于棋盘密码,它用字符表的坐标来代替坐;所以只有1-5,和playfair一样默认用 i 代替 j;这里没有特殊说明,密钥就取这个了
先转成数字,这里第一次犯了迷糊,因为不一定是以 aeiou 的顺序,还需要爆破,这就意味有120种可能;找到了现成的 python 库实现
看一遍就能懂,有一个坑,害我最后直接调试库里的代码才改正,就是这个参数必须给它大写的,不然后面会因为找不到而报错
exp
1 | #!/usr/bin/env python |
这个库有点东西
密码学AK赛
加法
1 | vtu[ypslg;sh}lrunpstf[sddeptf\ |
冥冥之中很熟悉,但却说不出来是啥加密;本来打算放弃,然后随便抽取一段出来出来搜,发现一篇CSDN的博客,讲的是为了使密码安全,将密码键位向右移动一位,所谓的键位就是在键盘上位置
手撕了
1 | cryptoakflag{keyboardpassword} |