[山海关crypto 训练营 day1]

老大终于对队伍里的密码手下手了(不是。。
老大召集队伍里的密码手一起刷crypto hack,一起上大分。为了更好的记录本次的学习成果决定对学习当中遇到的问题和收获做一些整理也算是对最近焦虑和压抑的科研生活做个调剂,而且crypto hack这个平台在网上公开的wp比较少,大家一起刷一波也能整理出不少wp供其他同学学习和参考,也算是公者千古了(不是。。
给自己点小鼓励:你要做冲出的黑马 而不是坠落的星星。

Signing Server (60pt)

题目描述

在这里插入图片描述

题目源代码

#!/usr/bin/env python3

from Crypto.Util.number import bytes_to_long, long_to_bytes
from utils import listener



class Challenge():
    def __init__(self):
        self.before_input = "Welcome to my signing server. You can get_pubkey, get_secret, or sign.\n"

    def challenge(self, your_input):
        if not 'option' in your_input:
            return {"error": "You must send an option to this server"}

        elif your_input['option'] == 'get_pubkey':
            return {"N": hex(N), "e": hex(E) }

        elif your_input['option'] == 'get_secret':
            secret = bytes_to_long(SECRET_MESSAGE)
            return {"secret": hex(pow(secret, E, N)) }

        elif your_input['option'] == 'sign':
            msg = int(your_input['msg'], 16)
            return {"signature": hex(pow(msg, D, N)) }

        else:
            return {"error": "Invalid option"}


listener.start_server(port=13374)

题目分析

奶奶滴,60分的题目咋这么水了。。。
首先,程序支持我们进行3种操作:
1.获得公钥(其实没用)
2.获得flag的密文
3.输入一个meg获得它的RSA数字签名
根据RSA的基础和数字签名的基础:
s e c r e t = f l a g E m o d ( N ) secret=flag^E mod (N) secret=flagEmod(N)
s i g n = m s g D m o d ( N ) sign=msg^Dmod(N) sign=msgDmod(N)
因此,首先我们可以调用加密函数,获得flag对应的secret,然后把secret作为msg输入获得它的数字签名,这个签名的过程也就相当于对密文进行解密,因此将获得十六进制抓化成ascii获得flag

具体操作

在这里插入图片描述

注意输入json格式
对上述信息进行解密
在这里插入图片描述

Let’s Decrypt (80pt)

题目描述

在这里插入图片描述

题目源代码

#!/usr/bin/env python3

import re
from Crypto.Hash import SHA256
from Crypto.Util.number import bytes_to_long, long_to_bytes
from utils import listener
from pkcs1 import emsa_pkcs1_v15
# from params import N, E, D

FLAG = "crypto{?????????????????????????????????}"

MSG = 'We are hyperreality and Jack and we own CryptoHack.org'
DIGEST = emsa_pkcs1_v15.encode(MSG.encode(), 256)
SIGNATURE = pow(bytes_to_long(DIGEST), D, N)


class Challenge():
    def __init__(self):
        self.before_input = "This server validates domain ownership with RSA signatures. Present your message and public key, and if the signature matches ours, you must own the domain.\n"

    def challenge(self, your_input):
        if not 'option' in your_input:
            return {"error": "You must send an option to this server"}

        elif your_input['option'] == 'get_signature':
            return {
                "N": hex(N),
                "e": hex(E),
                "signature": hex(SIGNATURE)
            }

        elif your_input['option'] == 'verify':
            msg = your_input['msg']
            n = int(your_input['N'], 16)
            e = int(your_input['e'], 16)

            digest = emsa_pkcs1_v15.encode(msg.encode(), 256)
            calculated_digest = pow(SIGNATURE, e, n)

            if bytes_to_long(digest) == calculated_digest:
                r = re.match(r'^I am Mallory.*own CryptoHack.org$', msg)
                if r:
                    return {"msg": f"Congratulations, here's a secret: {FLAG}"}
                else:
                    return {"msg": f"Ownership verified."}
            else:
                return {"error": "Invalid signature"}

        else:
            return {"error": "Invalid option"}


listener.start_server(port=13391)

题目分析

感谢队内KBU师傅的帮助,一开始我们俩都把这个题目想复杂了(其实是我误导了师傅,一直在考虑PKCS的那个cve,其实这个题目简单的很多

在这里插入图片描述
题目首先对MSG这句话进行签名得到SIGNATURE
我们的目标是构造一个msg(题目要求msg必须含有I am Mallory.*own CryptoHack.org这句话),传入e,n进行签名,要求是与题目给出的签名是相同的。

具体操作

首先,调用get_signature函数获得题目中的签名
在这里插入图片描述其实这里的n,e都是安全,没法利用。
然后,我们本地跑一下自己构造msg的digest

from pkcs1 import emsa_pkcs1_v15
msg="I am Mallory.*own CryptoHack.org"
digest = emsa_pkcs1_v15.encode(msg.encode(), 256)
print(digest.hex())

'''0001ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff003021300906052b0e03021a05000414f21168b397a142c7a3a7a635f5eef70f4bc9f30b'''

拿到flag的条件是:
s i g n a t u r e e   m o d   n = d i g e s t signature^e \ mod\ n =digest signaturee mod n=digest
现在我们已知 s i g n a t u r e signature signature d i g e s t digest digest题目需要我们构造 n , e n,e n,e满足上边的等式。这时,我们令e=1,得到
s i g n a t u r e   m o d   n = d i g e s t signature\ mod \ n=digest signature mod n=digest,即
s i g n a t u r e = k n + d i g e s t signature=kn+digest signature=kn+digest,k=1时, n = s i g n a t u r e − d i g e s t n=signature-digest n=signaturedigest,我们构造 n , e n,e n,e即可得到答案。
在这里插入图片描述传入拿flag
在这里插入图片描述

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值