Bugku题目Crypto密码部分wp(持续更新)

密码学基础

密码学研究加密、解密、在存在窃听环境中通信、在存在篡改环境中通信。

常见的对称加密

对称加密算法的分类:

  • 流密码/序列密码,用随机生成的序列,对每个字节(或二进制位)作用。安全性依赖于随机序列的随机数生成器。
  • 块密码/分组密码,将明文分块(如16字节128位),每个块和秘钥作用,再拼接出看似随机的序列。安全性依赖于块密码算法。

常见对称加密算法

  • AES,分组密码
  • DES/3DES,分组密码
  • RC4,序列密码

非对称加密算法

非对称加密算法,加密秘钥和解密秘钥不同,且无法互相推导。用公钥加密、私钥解密,可以实现用同一个私钥处理其他人发来的消息。用私钥加密、公钥解密,可以实现数字签名,只有用你的私钥加密的信息才能被正确的解密出来。

常见非对称加密算法

  • RSA,依赖于大整数分解的困难性
  • DSA,依赖于整数离散对数的困难性
  • ECDSA,依赖于椭圆曲线上离散对数的困难性

对称加密和非对称加密的应用

对称加密安全性依赖于混淆、扩散等操作。非对称加密安全性依赖于无法在可接受时间内求解的数学问题。对称加密的效率通常高于非对称加密,实际应用场景通常先通过非对称加密方式加密对称加密的秘钥,再用对称秘钥加密大量数据。

古典密码学

古典密码安全性依赖于算法的保密。对现代计算机来说古典密码学都比较容易破解。

密码学前沿

零知识认证:如何向别人证明,你拥有满足特定条件的信息,同时不泄露次信息。

安全多方计算:如何用多个人的秘密共同计算出一个结果,同时不泄露秘密。

量子密码学:量子计算机无法破解的密码学算法。

CTF密码学攻击方法

待完善。

抄错的字符

题目链接。描述: 老师让小明抄写一段话,结果粗心的小明把部分数字抄成了字母,还因为强迫症把所有字母都换成大写。你能帮小明恢复并解开答案吗:QWIHBLGZZXJSXZNVBZW 。看来有可能把数字抄成字母的有 O:0、I:1、L:1、Z:2、S:5、B:6、G:9、Q:9(这里值列举出大写字母对应数字的情况)。那么就可以爆破一下,猜测爆破之后还要base64转码一下,代码如下。

# -*- coding : utf-8 -*-
import base64


def resolve(s):
    # 可能抄错的数字和对应字母
    d = {'O': 0, 'I': 1, 'L': 1, 'Z': 2, 'S': 5, 'B': 6, 'G': 9, 'Q': 9}
    sdict = []

    # 每个字符都可能是大小写和原本的数字
    for c in s:
        sdict.append(c + c.lower() + (str(d.get(c)) if d.get(c) else ''))

    # 把可能的原来字符串都列出来
    result = ['']
    for sd in sdict:
        temp = []
        for sr in result:
            for c in sd:
                temp.append(sr + c)
        result = temp

    # 把可能的base64编码都搞出来
    b64result = []
    err = []
    for i, sr in enumerate(result):
        try:
            #
            s1 = base64.b64decode(sr.encode('utf-8'))
            s1 = s1.decode('utf-8')
            b64result.append(s1)
        except:
            try:
                sr = sr + '='
                s1 = base64.b64decode(sr.encode('utf-8'))
                s1 = s1.decode('utf-8')
                b64result.append(s1)
            except:
                try:
                    sr = sr + '=='
                    s1 = base64.b64decode(sr.encode('utf-8'))
                    s1 = s1.decode('utf-8')
                    b64result.append(s1)
                except:
                    err.append(sr)
    return b64result


def main():
    # base64 因此将密文分成4个一组
    m = 'QWIHBLGZZXJSXZNVBZW'
    mseg = []
    for i in range(0, len(m), 4):
        mseg.append(m[i:i + 4])
    print(mseg)

    # 遍历所有的字符串片段,拼接到一起
    flines = ['']
    for s in mseg:
        b64seg = resolve(s)
        temp = []
        for sf in flines:
            for sg in b64seg:
                temp.append(sf + sg)
        flines = temp

    # 每行都加上换行符
    for i, s in enumerate(flines):
        flines[i] = s + '\n'

    # 输出到文件
    f = open('抄错的字符.txt', 'w', encoding='utf-8')
    f.writelines(flines)
    f.close()


if __name__ == '__main__':
    main()

因为题目作者叫Aman,所以从爆破结果里找能读懂的字符串 flag{Aman_very_cool}

/.-【莫斯密码】

题目链接。很明显的摩斯密码。用随波逐流的摩斯码解密之后,全部转为小写即可。

描述: ..-./.-../.-/--./----.--/-../...--/..-./-.-./-.../..-./.----/--.../..-./----./...--/----./----./...../-----/....-/-----.-

FLAG{D3FCBF17F9399504}

flag{d3fcbf17f9399504}

[+-<>]【BrainFuck编码】

题目链接。描述: +++++ +++++ [->++ +++++ +++<] >++.+ +++++ .<+++ [->-- -<]>- -.+++ +++.< ++++[ ->+++ +<]>+ +++.< +++++ +++[- >---- ----< ]>--- ----- ---.< +++++ ++[-> +++++ ++<]> +++.< +++++ +[->- ----- <]>-- ----- -.--. ----. --.++ +++++ +.<++ ++++[ ->+++ +++<] >++++ +.++. <++++ ++[-> ----- -<]>- ----- ----. -.<++ +++++ [->++ +++++ <]>+. ----. ++++. <++++ +++[- >---- ---<] >---- .+.<+ +++++ ++[-> +++++ +++<] >++++ +++++ ++.<

BrainFuck解码得到 flag{0d86208ac54fbf12}

聪明的小羊【栅栏密码】

题目链接。描述: 一只小羊翻过了2个栅栏 fa{fe13f590lg6d46d0d0}。

栅栏密码解码,分为2栏时,解密结果为:flag{6fde4163df05d900}

把猪困在猪圈里【base64、猪圈密码】

题目链接。描述: flag{}。附件是 把猪困在猪圈里.txt,打开发现仅一行,以=结尾,猜测为base64编码。base64转码输出二进制文件,观察前16字节有0xFFDB为jpg的magic。代码如下。

# -*- coding:utf8 -*-
import base64

# 读取base64密文
f1 = open('把猪困在猪圈里.txt', 'r', encoding='utf-8')
c = f1.readline()
f1.close()

# base64解码,查看16个字节有没有magic
m = base64.b64decode(c)
print(m[0:16])

# 输出到二进制文件
f = open('把猪困在猪圈里.bin', 'wb')
f.write(m)
f.close()

猪圈密码(注意猪圈密码的画法)解密为  flag{thisispigpassword}

你喜欢下棋吗

题目链接。描述: 密码全为小写,格式bugku{}。附件有个 解压密码.txt 和 flag.zip。

你喜欢下棋吗?
解压密码为小写
4423244324433534315412244543

下棋,polybius密码也叫棋盘密码,解密得到thisispolybius,这是压缩包的密码。也可以用随波逐流。

"""
polybius密码,也叫棋盘密码
"""

TAB = [
    ['a', 'b', 'c', 'd', 'e'],
    ['f', 'g', 'h', 'ij', 'k'],
    ['l', 'm', 'n', 'o', 'p'],
    ['q', 'r', 's', 't', 'u'],
    ['v', 'w', 'x', 'y', 'z']]


def resovle(s):
    ms = ['']
    for i in range(0, len(s), 2):
        line, col = int(s[i]), int(s[i + 1])
        if 1 <= line <= 5 and 1 <= col <= 5:
            temp = []
            for m in ms:
                if line == 2 and col == 4:
                    temp.append(m + 'i')
                    temp.append(m + 'j')
                else:
                    temp.append(m + TAB[line - 1][col - 1])
            ms = temp
        else:
            raise IndexError(str(line) + ',' + str(col))
    return ms


def main():
    c = '4423244324433534315412244543'
    m = resovle(c)
    for s in m:
        print(s)
    pass


if __name__ == '__main__':
    main()

一种5bit的编码
bugku里面的内容为小写
bugku{11111 11001 00011 00111 01001 11011 10110 11111 10000 01110 11011 10110 11111 01001 00001} 

这里用到了博多密码(Baudot Code),解密代码如下,也可以随波逐流解码 。解码后根据描述转成小写得到 flag{baud0tc0de}

# -*- coding:utf8 -*-
"""
Baudot Code 一种5bit编码,比ASCII还要古老
0x00 是ascii的NULL
0x0A 是ascii的LF
0x0D 是ascii的CR
0x05 是ascii的ENQ
0x07 是ascii的BELL
"""

LETTERS = [chr(0x00), 'E', chr(0x0A), 'A', ' ', 'S', 'I', 'U', chr(0x0D), 'D',
           'R', 'J', 'N', 'F', 'C', 'K', 'T', 'Z', 'L', 'W', 'H', 'Y', 'P', 'Q',
           'O', 'B', 'G', 'Figures', 'M', 'X', 'V', 'Letters']
FIGURES = [chr(0x00), '3', chr(0x0A), '-', ' ', '\'', '8', '7', chr(0x0D),
           chr(0x05), '4', chr(0x07), ',', '!', ':', '(', '5', '+', ')', '2',
           '$', '6', '0', '1', '9', '?', '&', 'Figures', '.', '/', ';',
           'Letters']


def dec(c):
    tab = LETTERS
    m = ''
    for i in c:
        if LETTERS[i] == 'Letters':
            tab = LETTERS
        elif LETTERS[i] == 'Figures':
            tab = FIGURES
        else:
            m += tab[i]
    return m


def main():
    c = [0b11111, 0b11001, 0b00011, 0b00111, 0b01001, 0b11011, 0b10110, 0b11111,
         0b10000, 0b01110, 0b11011, 0b10110, 0b11111, 0b01001, 0b00001]
    m = dec(c)
    print(m)


if __name__ == '__main__':
    main()

ok

题目链接。描述: Ook.。那就Ook解码一下,github上有个项目gil9red/Ook: Ook! Interpreter (Python),推荐使用。解码得到 flag{0a394df55312c51a}

小山丘的秘密

题目链接。描述: hill能有什么秘密呢。附件有2个。flag.txt的内容如下,小山丘的秘密.jpg图片如下

bugku{PLGTGBQHM}

其中A=1,flag全为小写

 hill音译为希尔,也就是希尔密码。密文为PLGTGBQHM,加密矩阵如棋盘,通过如下代码可以解密,自己转小写即可 bugku{whatahill}

"""
希尔密码是运用基本矩阵论原理的替换密码,由Lester S. Hill在1929年发明。

每个字母当作26进制数字:A=0, B=1, C=2... 一串字母当成n维向量,跟一个n×n的矩阵相乘,再将得出的结果模26。
(注意用作加密的矩阵(即密匙)在 必须是可逆的,否则就不可能解码。只有矩阵的行列式和26互质,才是可逆的。)
"""
import numpy as np


def string_to_array(string, size, offset):
    string = string.upper()
    blocks = [string[i:i + size] for i in range(0, len(string), size)]
    if len(blocks[-1]) != size:  # 补齐成矩阵
        blocks[-1] = blocks[-1].ljust(size, chr(ord('A') - offset))
    arr = np.array([list(map(ord, block)) for block in blocks]) - ord(
        'A') + offset
    return arr


def encode(encryptor, string, offset=0):
    '''
    希尔加密
    :param encryptor: 加密矩阵
    :param string: 明文
    :param offset: 默认A=0
    :return: 密文
    '''
    assert encryptor.ndim == 2 and encryptor.shape[0] == encryptor.shape[1]

    arr = string_to_array(string, encryptor.shape[0], offset)  # 字符串转数字矩阵
    result = (encryptor @ arr.T).T % 26 + ord('A') - offset  # 算法
    result = ''.join(map(chr, result.ravel()))  # 数字矩阵转字符串
    return result


def decode(decryptor, string, offset=0):
    '''
    希尔解密,算法和加密一样
    :param decryptor: 解密矩阵
    :param string: 密文
    :param offset: 默认A=0
    :return: 明文
    '''
    assert decryptor.ndim == 2 and decryptor.shape[0] == decryptor.shape[1]

    arr = string_to_array(string, decryptor.shape[0], offset)  # 字符串转数字矩阵
    result = (decryptor @ arr.T).T % 26 + ord('A') - offset  # 算法
    result = ''.join(map(chr, map(int, result.ravel())))  # 数字矩阵转字符串
    return result


if __name__ == '__main__':
    en_matrix = np.array([[1, 2, 3], [0, 1, 4], [5, 6, 0]])
    de_matrix = np.array(np.linalg.inv(en_matrix), dtype=int)
    c_msg = 'PLGTGBQHM'
    m_msg = decode(de_matrix, c_msg, offset=1)  # Bugku题目说A=1,就是offset=1
    print(m_msg)

next

题目链接。

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

苦行僧(csdn)

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值