青龙组
签到
答对八道知识问答题,得到flag:
crypto091
根据题目意思电话号码前几位为1709,因为通过百度可以查找到170号段首批放号的联通号是1709开头;又根据hash值长度64位hex猜测是sha256,于是带上地区码86爆破哈希,得到正确的电话号码:
1 | from hashlib import * |
带上flag格式提交即可。
补一个美观一点的exp:
1 | x = 'c22a563acc2a587afbfaaaa6d67bc6e628872b00bd7e998873881f7c6fdc62fc' |
crypto162
$\left[\begin{matrix}an\a{n-1}\a{n-2}\end{matrix}\right]=\left[\begin{matrix}t_0&t_1&t_2\1&0&0\0&1&0\end{matrix}\right]*\left[\begin{matrix}a{n-1}\a{n-2}\a{n-3}\end{matrix}\right]$
sage矩阵快速幂运算即可:
1 | from Crypto.Util.number import * |
crypto405
选取了5个初始$key$:$k_0,k_1,k_2,k_3,k_4$,$grasshopper=grasshpper.k_0.k_1.k_2.k_3.k_4$,$key$是不断在累乘的,而$flag$的格式为flag{
,可以通过这五个明文字符来求$key$,比赛时我们的思路是硬解方程组恢复密钥,赛后看到一个很有意思的思路,于是复现一下。
首先列出开头五个字符的变换式子,用$var$赋值打印看看大致情况:
1 | flag = b'flag{' |
可以看到由于$key$累乘,其次数每一轮都在增大,而由于$flag$的字符也在累乘,其系数也在不断增大。
这个思路的关键部分是把乘法看成加法,次幂看成乘法,那么该五组式子就可以看成线性方程组用矩阵处理,将该矩阵通过行列变换得到单位矩阵,那么就能求出$key$(行列变化的加法和乘法分别为乘法和次幂,减法为乘上逆元):
求出$key$以后再恢复$flag$即可。
1 | # 预处理 |
这只是一个demo,解矩阵方程的方法需要自己重写,和加、乘不同;这里主要是学习解题思路。
re694
修改了upx壳的节区名 手动恢复后脱壳 用ida分析 非常简单的加密后check 逆向解密即可
1 | res = [0x4B,0x48,0x79,0x13,0x45,0x30,0x5C,0x49,0x5A,0x79,0x13,0x70,0x6D,0x78,0x13,0x6F,0x48,0x5D, 0x64,0x64] |
白虎组
simple_math
1 | import gmpy2 |
easywork
垃圾题,,,滚
1 | from Crypto.Util.number import * |
朱雀组
misc666
题目把base32的表改了,数字2-7改成了数字1-6,大写字母改成了小写;于是把小写换为大写,数字加1再解密即可:flag{NiuDaoxiaoshi666}
crypto967
1 | # ph算法求解离散对数,找两个乘起来比x大的因子计算再crt即可 |
玄武组
crypto557
考察二次剩余以及概率统计,类似于国外ictf的一道题。整个题目的关键点在if分支:
1 | for j in range(size(tmp)):#比特数 |
如果x对于p是二次剩余的话,这里的pow(x,r,p)也一定为二次剩余,此时flag为1的位对应的enc中元素
必定为p的二次剩余;与之相对的,enc中元素不是p的二次剩余的时候,对应的flag二进制位必为0。
题目给了18组数据,一定会有某些组的x为p的二次剩余,判断方法为对每一组数字进行二次剩余占比的统计,若占比大于60%,基本可以判断该组的x为p的二次剩余。
利用这些筛选出的组,我们可以通过实现上述加粗理论确定0位。由于flag某位为0的时候,r也可能为二次剩余,因此我们需要统计18组的二次非剩余的位置,以免漏掉一些0位。我的方法是把每组二次非剩余对应的位赋值为1,然后把各个组进行或运算操作,最后各位取一下反即可。
完整的exp:(数据很大没放)
1 | p_l = [] |