西湖论剑CTF2019

这篇博客详细介绍了参与西湖论剑CTF2019比赛时遇到的Crypto和Misc类别题目。在哈夫曼之谜中,通过建立哈夫曼树解密了文件。Hardgame部分涉及了三个加密flag,包括DES-ECB-PKCS5加密的解密过程。在Misc题目中,解决了一个寻找最短路径的问题。博主提供了解题思路和解密脚本,分享了从密文到明文的转换方法。

Crypto

哈夫曼之谜

11317931-eaf35561b43e637c.png
哈夫曼.png

下载下来就一个文件,里面全是0101和一些字符。
搜索哈夫曼,了解到哈夫曼压缩时用到的哈夫曼树
猜测下面的字符代表频率。
哈夫曼树建立过程如下

11317931-e5490e4457f672dc.gif
哈夫曼树建立.gif

字符不多,直接在草稿纸上手写。
11317931-f1e18b187fb40c0f.jpg
哈夫曼手写.jpg

圆圈内就是构建好后对应字符的 哈夫曼编码
在建立过程中,对于频率相同的字符在不同程序上排序的前后顺序可能不同,所以存在相同频率的字符哈夫曼编码不同。比如字符5和字符d的频率都是9,则字符d的哈夫曼编码可以是01,也可以是10。
然后对上面的01串进行解码,一般是以 flag{ 开头,所以前几个字符的哈夫曼编码可以确定下来。
但字符5和字符d的无法确定,所以得到两个flag。
flag{ddf5dfd0f05550500a5af55dd0d5d0ad}
flag{55fd5f50f0ddd0d00adafdd5505d50a5}
都提交上去就可以了


Hardgame

11317931-d7e829456b91a7fe.png
Hardgame.png

有三个flag,三段加密。

flag1

加密如下

11317931-708694af1566b6a8.png
Hardgame-flag1.png

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个字节进行计算(并行计算),之后按照顺序将计算所得的数据连在一起即可,各段数据之间互不影响。


11317931-afea7db741a20784.png
ECB.png

填充使用的是PKCS5,就是全部填充到8字节,后面缺几位就填几
如:后面缺4个字节,就填04040404;
8个字节都是空,就填0808080808080808


11317931-9b67ed763a5f42f9.png
PKCS5.png

该算法对很多行明文按行分开加密,密钥是8字节,ECB加密是8字节一组,如果遇到空的8字节,就会出现填充后明文为0808080808080808与密文段进行异或。

截取各行密文的后8字节,统计发现ea9c3c12181a1e8216d0aa455a272fde都出现过多次。
将密文放进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

11317931-0079a18166a71942.png
flag2.png

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=0x834b44a67ea419e1c3e665cedf7790ebc5fb013e2304861b667232e7ec1cae53eb253639b348a6702561671a5c5c9105eacd5d48de51427fc49f22ed2d9b60f98c5071
03-08
在编程中,“flag”(标志)是一种常用的变量类型,主要用于表示某种状态或条件是否成立。它通常是布尔型(bool)、整型(int)等简单的数据类型。通过设置和检查标志位的状态,程序员可以控制程序流程、判断特定事件的发生与否以及简化复杂的逻辑操作。 ### 标志的具体应用示例: 1. **循环控制** - 使用一个布尔类型的 `flag` 来指示某个任务是否已完成: ```c bool taskCompleted = false; // 初始化为未完成 while (!taskCompleted) { // 执行一些操作... if (/*满足结束条件*/) { taskCompleted = true; // 设置标志表明任务已完cheng成 } } ``` 2. **错误检测** - 利用整数或其他枚举类型的 `flag` 可以标识不同种类的错误信息: ```python error_flag = 0 # 假设 0 表示无错误, 非零值表示不同类型错误 try: # 某些可能会抛出异常的操作... except SpecificException as e: error_flag = 1 # 发生了SpecificException 错误 print("Error status:", "OK" if not error_flag else f"Failed with code {error_flag}") ``` 3. **开关功能** - 在图形用户界面或者命令行工具里,可以用布尔 `flag` 实现开启/关闭某项特性: ```bash --verbose # 开启详细模式 ``` 4. **状态跟踪** - 对于复杂业务逻辑而言,可能需要多个标志共同维护整个系统的运行状况: ```cpp enum StateFlags { STATE_IDLE, STATE_LOADING, STATE_READY, STATE_ERROR }; int stateFlag = STATE_IDLE; switch(stateFlag){ case STATE_IDLE : /*...*/ break; case STATE_LOADING : /*...*/ break; case STATE_READY : /*...*/ break; default: ;//处理STATE_ERROR或者其他未知状态 } ``` 总之,在各种编程语言和场景下都可以看到“flags”的身影,它们帮助开发者更好地管理和响应应用程序内部的变化,提高代码的清晰度及可读性。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值