Crypto
哈夫曼之谜
下载下来就一个文件,里面全是0101和一些字符。
搜索哈夫曼,了解到哈夫曼压缩时用到的哈夫曼树
。
猜测下面的字符代表频率。
哈夫曼树建立过程如下
字符不多,直接在草稿纸上手写。
圆圈内就是构建好后对应字符的
哈夫曼编码
。
在建立过程中,对于频率相同的字符在不同程序上排序的前后顺序可能不同,所以存在相同频率的字符哈夫曼编码不同。比如字符5和字符d的频率都是9,则字符d的哈夫曼编码可以是01,也可以是10。
然后对上面的01串进行解码,一般是以
flag{
开头,所以前几个字符的哈夫曼编码可以确定下来。
但字符5和字符d的无法确定,所以得到两个flag。
flag{ddf5dfd0f05550500a5af55dd0d5d0ad}
flag{55fd5f50f0ddd0d00adafdd5505d50a5}
都提交上去就可以了
Hardgame
有三个flag,三段加密。
flag1
加密如下
RSA加密,由于e只有2,相当于把明文m平方而已,得到的c也比n小很多。
尝试把c开根号看能否得到明文。
一般的python开根号方法精度较低,对大整数开出来的根号准确度低。
发现使用
gmpy2
库可以对大整数开根号。
import gmpy2
import libnum
c = 9217979941366220275377875095861710925207028551771520610387238734819759256223080175603032167658086669886661302962985046348865181740591251321966682848536331583243529
m = gmpy2.isqrt(c)
m = int(m)
m_text = libnum.n2s(m)
print(m_text)
得到flag1flag1{Th1s_i5_wHat_You_ne3d_FirsT}
flag2
加密过程是DES-ECB-PKCS5,密钥是随机的8字节的大写字母
DES ECB(电子密本方式)其实非常简单,就是将数据按照8个字节一段进行DES加密或解密得到一段段的8个字节的密文或者明文,最后一段不足8个字节(一般补0或者F),按照需求补足8个字节进行计算(并行计算),之后按照顺序将计算所得的数据连在一起即可,各段数据之间互不影响。
填充使用的是PKCS5,就是全部填充到8字节,后面缺几位就填几
如:后面缺4个字节,就填04040404;
8个字节都是空,就填0808080808080808
该算法对很多行明文按行分开加密,密钥是8字节,ECB加密是8字节一组,如果遇到空的8字节,就会出现填充后明文为0808080808080808与密文段进行异或。
截取各行密文的后8字节,统计发现ea9c3c12181a1e82
和16d0aa455a272fde
都出现过多次。
将密文放进hashcat进行爆破
hashcat64.exe -a 3 -m 14000 d33ad316eb246e5c:0808080808080808 -w 3 -O ?u?u?u?u?u?u?u?u
hashcat64.exe -a 3 -m 14000 ea9c3c12181a1e82:0808080808080808 -w 3 -O ?u?u?u?u?u?u?u?u
d33ad316eb246e5c解不出来
ea9c3c12181a1e82很快可得到密钥为
JFRYOMPR
然后解密脚本如下
from pyDes import *
Des_Key = "JFRYOMPR"
def DesDecrypt(str):
k = des(Des_Key, ECB, pad=None, padmode=PAD_PKCS5)
DecryptStr = k.decrypt(str.decode('hex'))
return DecryptStr
with open('enc.txt','r') as fe:
for line in fe.readlines():
print DesDecrypt(line.strip('\n'))
得到flag2flag2{Fuck_Y0u_cAn_Ge7_Se3ond}
再看最终的flag
用的是rsa加密
n放到factordb无法解密
e也足够大
这里的加密用了类似于CBC的方式,区别在于先加密再异或
但分组长度过短,2字节一组
所以可以构建一个明文于密文的对应字典,通过查找的方式找回原文
且由于是先加密后异或,所以可以从后往前按顺序找出每个分组异或前的加密结果
解密脚本如下
#!usr/bin/env python
# -*- coding: utf-8 -*-
import base64
import binascii
import string
import libnum
from Crypto.Util import number
from Crypto.Util.strxor import strxor
n=0x834b44a67ea419e1c3e665cedf7790ebc5fb013e2304861b667232e7ec1cae53eb253639b348a6702561671a5c5c9105eacd5d48de51427fc49f22ed2d9b60f98c50713ac95f2ac324fa58b90e0c07ab688becb771d92224be68474586376a4cd9a0ea96d5584184cbb7ad3889fd6c1a4ae3791e67a4ee6f220491abbbda2006addc6032999238cc010df759c868485522ee17e520569b7e746b0c770065f4622894afcfd46257b7c3646f15d65d561ab8e22e4f03cfbfa53ec4109115feeced84c398286bb79c58a7d640a2faec2c50285558d6b11d8ebc25eae6ece9c418dd795c0c11f459c815582c059935028cafb09b6603cc44a48f3823d0aeda73fec7
e=0x9ae923
c="L+HK7Ksu+PoVJZBnIriWufZgKFH1APFFLFnKIf7OFjlBHRAk