首页 > 其他分享 >2023年国家基地“楚慧杯”网络安全实践能力竞赛初赛-Crypto+Misc WP

2023年国家基地“楚慧杯”网络安全实践能力竞赛初赛-Crypto+Misc WP

时间:2023-12-18 18:22:53浏览次数:47  
标签:affected BB Misc 初赛 ii jj 2023 print monomials

Misc

ez_zip

题目

4096个压缩包套娃

我的解答:

写个脚本直接解压即可:

import zipfile
 
name = '附件路径\\题目附件.zip'
for i in range(4097):
    f = zipfile.ZipFile(name , 'r')
    f.extractall(pwd=name[:-4].encode())
    name = f.filelist[0].filename
    print(name[:-4],end="")
    f.close()

得到

+-+++-++ +-+++++- +-+-++-- +-++++-- +-+-+-++ +-+++--+ +----+-- ++--+++- ++--++++ +--+++-- ++--+-+- ++---+++ ++--++-+ ++--+-+- ++---+++ +--+++-- +--+++-- +--++--+ ++--+++- +--++-+- ++--+--- +--+++-- ++--+--+ ++--++-- ++--+++- +--++-+- ++--+-+- ++---++- ++--+++- ++--+++- +--++-+- +--++-++ ++--+--+ +--++++- +--+++-- +--+++-- ++--+-++ +--++-+- +--++-++ +-----+-

一眼丁真01,将+改成0,-改成1

x='''01000100 01000001 01010011 01000011 01010100 01000110 01111011 00110001 00110000 01100011 00110101 00111000 00110010 00110101 00111000 01100011 01100011 01100110 00110001 01100101 00110111 01100011 00110110 00110011 00110001 01100101 00110101 00111001 00110001 00110001 01100101 01100100 00110110 01100001 01100011 01100011 00110100 01100101 01100100 01111101'''
s=x.split(' ')
print(''.join(chr(int(c,2)) for c in s))

'DASCTF{10c58258ccf1e7c631e5911ed6acc4ed}'

easy取证

题目

我的解答:

一个取证问题,简单来分析一下:

本人是在windows下使用,参考:https://blog.csdn.net/m0_68012373/article/details/127419463

我们先查看镜像信息

volatility.exe -f mem.raw imageinfo

然后我们可以利用插件grep查找一下常见的信息,例如:zip,txt,docx,png,jpg等

测试之后发现桌面有个docx文档

volatility.exe -f mem.raw --profile Win7SP1x64 filescan | grep .docx

我们需要提取出来

volatility.exe -f mem.raw --profile=Win7SP1x64 dumpfiles -Q 0x000000003dceaf20 -D ./

得到

修改后缀为docx打开,复制内容到txt里面

一眼丁真snow隐写,但需要找到密码,我们使用mimikatzmimikatz插件可以获取系统明文密码,网上有安装教程)获取密码

得到

H7Qmw_X+WB6BXDXa

然后直接解码即可

SNOW.EXE -C -p "H7Qmw_X+WB6BXDXa" White.txt

Crypto

so-large-e

题目

公钥

-----BEGIN PUBLIC KEY-----
MIIBIDANBgkqhkiG9w0BAQEFAAOCAQ0AMIIBCAKBgQCl7ZhtXDOIFdSnnejtOn2W
OdcqyzrvKMVFTIqSyPV3Tkj5m9ETc/rlvLJLcQvI0V6tr+u5Tq+zqWBQzsvRsvKt
+ap0JW8up0qD1nGIvcJVdsWAjdse7AH/N3+xg8NrH3nO0OIWzMpkGH+4TVsOBu8M
nhnR9SxTkDp+gUtHtPR/awKBgQChjp2PFfpCV4hrVyPJrKP2gHbW+o7mBNiUd3Av
Ucbkr7rA6Sj3tU33yGKIoXbmZC4rWNcuqrsoCPvIFl/YHYPKVDOl2PlLaDVi/Q5E
ymGkUfPXoZsScxvkZtkOt9XY4wWEeDMtxF/swnV0nhAUSJEHamFL3i0PAWf9uBdd
VheH4Q==
-----END PUBLIC KEY-----
from Crypto.Util.number import *
from Crypto.PublicKey import RSA
from flag import flag
import random

m = bytes_to_long(flag)

p = getPrime(512)
q = getPrime(512)
n = p*q
e = random.getrandbits(1024)
assert size(e)==1024
phi = (p-1)*(q-1)
assert GCD(e,phi)==1
d = inverse(e,phi)
assert size(d)==269

pub = (n, e)
PublicKey = RSA.construct(pub)
with open('pub.pem', 'wb') as f :
    f.write(PublicKey.exportKey())

c = pow(m,e,n)
print('c =',c)

print(long_to_bytes(pow(c,d,n)))


#c = 6838759631922176040297411386959306230064807618456930982742841698524622016849807235726065272136043603027166249075560058232683230155346614429566511309977857815138004298815137913729662337535371277019856193898546849896085411001528569293727010020290576888205244471943227253000727727343731590226737192613447347860

我的解答:

我们先分解公钥得到n,e

from gmpy2 import *
from Crypto.Util.number import *
from Crypto.PublicKey import RSA


# 公钥提取
with open("pub.pem","r",encoding="utf-8") as file:
    text=file.read()
key=RSA.import_key(text)
e=key.e
n=key.n
print(e)
print(n)

113449247876071397911206070019495939088171696712182747502133063172021565345788627261740950665891922659340020397229619329204520999096535909867327960323598168596664323692312516466648588320607291284630435682282630745947689431909998401389566081966753438869725583665294310689820290368901166811028660086977458571233
116518679305515263290840706715579691213922169271634579327519562902613543582623449606741546472920401997930041388553141909069487589461948798111698856100819163407893673249162209631978914843896272256274862501461321020961958367098759183487116417487922645782638510876609728886007680825340200888068103951956139343723

发现这个e很大,我们根据题目代码可知它跟n一个数量级。而d很小,想到维纳攻击或低解密指数攻击。但尝试无果有报错。问题就在于他的私钥太小d < N^0.292并不满足维纳或低解密d的要求。

因此我们需要爆出真正的满足题目条件的d,利用LLL-attacks解出d

详细解析可参考:https://github.com/Gao-Chuan/RSA-and-LLL-attacks/blob/master/boneh_durfee.sage

from __future__ import print_function
import time

############################################
# Config
##########################################

"""
Setting debug to true will display more informations
about the lattice, the bounds, the vectors...
"""
debug = True

"""
Setting strict to true will stop the algorithm (and
return (-1, -1)) if we don't have a correct
upperbound on the determinant. Note that this
doesn't necesseraly mean that no solutions
will be found since the theoretical upperbound is
usualy far away from actual results. That is why
you should probably use `strict = False`
"""
strict = False

"""
This is experimental, but has provided remarkable results
so far. It tries to reduce the lattice as much as it can
while keeping its efficiency. I see no reason not to use
this option, but if things don't work, you should try
disabling it
"""
helpful_only = True
dimension_min = 7 # stop removing if lattice reaches that dimension

############################################
# Functions
##########################################

# display stats on helpful vectors
def helpful_vectors(BB, modulus):
    nothelpful = 0
    for ii in range(BB.dimensions()[0]):
        if BB[ii,ii] >= modulus:
            nothelpful += 1

    print(nothelpful, "/", BB.dimensions()[0], " vectors are not helpful")

# display matrix picture with 0 and X
def matrix_overview(BB, bound):
    for ii in range(BB.dimensions()[0]):
        a = ('%02d ' % ii)
        for jj in range(BB.dimensions()[1]):
            a += '0' if BB[ii,jj] == 0 else 'X'
            if BB.dimensions()[0] < 60:
                a += ' '
        if BB[ii, ii] >= bound:
            a += '~'
        print(a)

# tries to remove unhelpful vectors
# we start at current = n-1 (last vector)
def remove_unhelpful(BB, monomials, bound, current):
    # end of our recursive function
    if current == -1 or BB.dimensions()[0] <= dimension_min:
        return BB

    # we start by checking from the end
    for ii in range(current, -1, -1):
        # if it is unhelpful:
        if BB[ii, ii] >= bound:
            affected_vectors = 0
            affected_vector_index = 0
            # let's check if it affects other vectors
            for jj in range(ii + 1, BB.dimensions()[0]):
                # if another vector is affected:
                # we increase the count
                if BB[jj, ii] != 0:
                    affected_vectors += 1
                    affected_vector_index = jj

            # level:0
            # if no other vectors end up affected
            # we remove it
            if affected_vectors == 0:
                print("* removing unhelpful vector", ii)
                BB = BB.delete_columns([ii])
                BB = BB.delete_rows([ii])
                monomials.pop(ii)
                BB = remove_unhelpful(BB, monomials, bound, ii-1)
                return BB

            # level:1
            # if just one was affected we check
            # if it is affecting someone else
            elif affected_vectors == 1:
                affected_deeper = True
                for kk in range(affected_vector_index + 1, BB.dimensions()[0]):
                    # if it is affecting even one vector
                    # we give up on this one
                    if BB[kk, affected_vector_index] != 0:
                        affected_deeper = False
                # remove both it if no other vector was affected and
                # this helpful vector is not helpful enough
                # compared to our unhelpful one
                if affected_deeper and abs(bound - BB[affected_vector_index, affected_vector_index]) < abs(bound - BB[ii, ii]):
                    print("* removing unhelpful vectors", ii, "and", affected_vector_index)
                    BB = BB.delete_columns([affected_vector_index, ii])
                    BB = BB.delete_rows([affected_vector_index, ii])
                    monomials.pop(affected_vector_index)
                    monomials.pop(ii)
                    BB = remove_unhelpful(BB, monomials, bound, ii-1)
                    return BB
    # nothing happened
    return BB

""" 
Returns:
* 0,0   if it fails
* -1,-1 if `strict=true`, and determinant doesn't bound
* x0,y0 the solutions of `pol`
"""
def boneh_durfee(pol, modulus, mm, tt, XX, YY):
    """
    Boneh and Durfee revisited by Herrmann and May
    
    finds a solution if:
    * d < N^delta
    * |x| < e^delta
    * |y| < e^0.5
    whenever delta < 1 - sqrt(2)/2 ~ 0.292
    """

    # substitution (Herrman and May)
    PR.<u, x, y> = PolynomialRing(ZZ)
    Q = PR.quotient(x*y + 1 - u) # u = xy + 1
    polZ = Q(pol).lift()

    UU = XX*YY + 1

    # x-shifts
    gg = []
    for kk in range(mm + 1):
        for ii in range(mm - kk + 1):
            xshift = x^ii * modulus^(mm - kk) * polZ(u, x, y)^kk
            gg.append(xshift)
    gg.sort()

    # x-shifts list of monomials
    monomials = []
    for polynomial in gg:
        for monomial in polynomial.monomials():
            if monomial not in monomials:
                monomials.append(monomial)
    monomials.sort()
    
    # y-shifts (selected by Herrman and May)
    for jj in range(1, tt + 1):
        for kk in range(floor(mm/tt) * jj, mm + 1):
            yshift = y^jj * polZ(u, x, y)^kk * modulus^(mm - kk)
            yshift = Q(yshift).lift()
            gg.append(yshift) # substitution
    
    # y-shifts list of monomials
    for jj in range(1, tt + 1):
        for kk in range(floor(mm/tt) * jj, mm + 1):
            monomials.append(u^kk * y^jj)

    # construct lattice B
    nn = len(monomials)
    BB = Matrix(ZZ, nn)
    for ii in range(nn):
        BB[ii, 0] = gg[ii](0, 0, 0)
        for jj in range(1, ii + 1):
            if monomials[jj] in gg[ii].monomials():
                BB[ii, jj] = gg[ii].monomial_coefficient(monomials[jj]) * monomials[jj](UU,XX,YY)

    # Prototype to reduce the lattice
    if helpful_only:
        # automatically remove
        BB = remove_unhelpful(BB, monomials, modulus^mm, nn-1)
        # reset dimension
        nn = BB.dimensions()[0]
        if nn == 0:
            print("failure")
            return 0,0

    # check if vectors are helpful
    if debug:
        helpful_vectors(BB, modulus^mm)
    
    # check if determinant is correctly bounded
    det = BB.det()
    bound = modulus^(mm*nn)
    if det >= bound:
        print("We do not have det < bound. Solutions might not be found.")
        print("Try with highers m and t.")
        if debug:
            diff = (log(det) - log(bound)) / log(2)
            print("size det(L) - size e^(m*n) = ", floor(diff))
        if strict:
            return -1, -1
    else:
        print("det(L) < e^(m*n) (good! If a solution exists < N^delta, it will be found)")

    # display the lattice basis
    if debug:
        matrix_overview(BB, modulus^mm)

    # LLL
    if debug:
        print("optimizing basis of the lattice via LLL, this can take a long time")

    BB = BB.LLL()

    if debug:
        print("LLL is done!")

    # transform vector i & j -> polynomials 1 & 2
    if debug:
        print("looking for independent vectors in the lattice")
    found_polynomials = False
    
    for pol1_idx in range(nn - 1):
        for pol2_idx in range(pol1_idx + 1, nn):
            # for i and j, create the two polynomials
            PR.<w,z> = PolynomialRing(ZZ)
            pol1 = pol2 = 0
            for jj in range(nn):
                pol1 += monomials[jj](w*z+1,w,z) * BB[pol1_idx, jj] / monomials[jj](UU,XX,YY)
                pol2 += monomials[jj](w*z+1,w,z) * BB[pol2_idx, jj] / monomials[jj](UU,XX,YY)

            # resultant
            PR.<q> = PolynomialRing(ZZ)
            rr = pol1.resultant(pol2)

            # are these good polynomials?
            if rr.is_zero() or rr.monomials() == [1]:
                continue
            else:
                print("found them, using vectors", pol1_idx, "and", pol2_idx)
                found_polynomials = True
                break
        if found_polynomials:
            break

    if not found_polynomials:
        print("no independant vectors could be found. This should very rarely happen...")
        return 0, 0
    
    rr = rr(q, q)

    # solutions
    soly = rr.roots()

    if len(soly) == 0:
        print("Your prediction (delta) is too small")
        return 0, 0

    soly = soly[0][0]
    ss = pol1(q, soly)
    solx = ss.roots()[0][0]

    #
    return solx, soly

def example():
    ############################################
    # How To Use This Script
    ##########################################

    #
    # The problem to solve (edit the following values)
    #

    # the modulus
    e = 113449247876071397911206070019495939088171696712182747502133063172021565345788627261740950665891922659340020397229619329204520999096535909867327960323598168596664323692312516466648588320607291284630435682282630745947689431909998401389566081966753438869725583665294310689820290368901166811028660086977458571233
    N = 116518679305515263290840706715579691213922169271634579327519562902613543582623449606741546472920401997930041388553141909069487589461948798111698856100819163407893673249162209631978914843896272256274862501461321020961958367098759183487116417487922645782638510876609728886007680825340200888068103951956139343723

    # the hypothesis on the private exponent (the theoretical maximum is 0.292)
    delta = .27 # this means that d < N^delta

    #
    # Lattice (tweak those values)
    #

    # you should tweak this (after a first run), (e.g. increment it until a solution is found)
    m = 6 # size of the lattice (bigger the better/slower)

    # you need to be a lattice master to tweak these
    t = int((1-2*delta) * m)  # optimization from Herrmann and May
    X = 2*floor(N^delta)  # this _might_ be too much
    Y = floor(N^(1/2))    # correct if p, q are ~ same size

    #
    # Don't touch anything below
    #

    # Problem put in equation
    P.<x,y> = PolynomialRing(ZZ)
    A = int((N+1)/2)
    pol = 1 + x * (A + y)

    #
    # Find the solutions!
    #

    # Checking bounds
    if debug:
        print("=== checking values ===")
        print("* delta:", delta)
        print("* delta < 0.292", delta < 0.292)
        print("* size of e:", int(log(e)/log(2)))
        print("* size of N:", int(log(N)/log(2)))
        print("* m:", m, ", t:", t)

    # boneh_durfee
    if debug:
        print("=== running algorithm ===")
        start_time = time.time()

    solx, soly = boneh_durfee(pol, e, m, t, X, Y)

    # found a solution?
    if solx > 0:
        print("=== solution found ===")
        if False:
            print("x:", solx)
            print("y:", soly)

        d = int(pol(solx, soly) / e)
        print("private key found:", d)
    else:
        print("=== no solution was found ===")

    if debug:
        print(("=== %s seconds ===" % (time.time() - start_time)))

if __name__ == "__main__":
    example()

之后直接解即可

import gmpy2
from Crypto.Util.number import *

d=663822343397699728953336968317794118491145998032244266550694156830036498673227937
c = 6838759631922176040297411386959306230064807618456930982742841698524622016849807235726065272136043603027166249075560058232683230155346614429566511309977857815138004298815137913729662337535371277019856193898546849896085411001528569293727010020290576888205244471943227253000727727343731590226737192613447347860
n=116518679305515263290840706715579691213922169271634579327519562902613543582623449606741546472920401997930041388553141909069487589461948798111698856100819163407893673249162209631978914843896272256274862501461321020961958367098759183487116417487922645782638510876609728886007680825340200888068103951956139343723
m=pow(c,d,n)
print(long_to_bytes(m))
#DASCTF{6f4fadce-5378-d17f-3c2d-2e064db4af19}

 

标签:affected,BB,Misc,初赛,ii,jj,2023,print,monomials
From: https://www.cnblogs.com/xiaoqi-ctf/p/17911881.html

相关文章

  • 云原生周刊:Kubernetes v1.29 正式发布 | 2023.12.18
    开源项目推荐RobustaKRRRobustaKRR(KubernetesResourceRecommender)是一个用于优化Kubernetes集群中资源分配的CLI工具。它从Prometheus收集Pod使用数据,并建议CPU和内存的请求和限制。这降低了成本并提高了性能。LiqoLiqo是一个开源项目,可实现动态、无缝的Kuber......
  • 2023-12-18 每天一练
    LeetCode每日一题162.寻找峰值问题峰值元素是指其值严格大于左右相邻值的元素。给你一个整数数组nums,找到峰值元素并返回其索引。数组可能包含多个峰值,在这种情况下,返回任何一个峰值所在位置即可。你可以假设nums[-1]=nums[n]=-∞。你必须实现时间复杂度为O(log......
  • 零数科技双平台入选2023爱分析·数据要素流通厂商全景报告
    全面近日,国内领先的数字化市场研究咨询机构爱分析正式发布《2023爱分析·数据要素流通厂商全景报告》,零数科技凭借成熟的区块链和隐私计算技术,及系列标杆产品及应用,成功入选数据要素流通代表厂商。图:零数科技入围爱分析数据要素厂商全景地图随着数字经济的崛起,数据成为推动社会生产......
  • 活动预告 | 2023CCF中国区块链技术与应用高峰论坛议程发布
    党的二十大报告明确提出要建设数字中国,加快发展数字经济。区块链作为数字经济的重要支撑技术,在不同行业领域中已得到了广泛应用,并深度赋能社会和经济发展。为进一步加快区块链技术与应用深度结合,促进区块链产业发展,驱动区块链更好赋能数字经济,由中国计算机学会(CCF)主办,CCF区块链专业......
  • [THUPC 2024 初赛] 三步棋
    鸣谢cinccout。赛时两次看出了我的错误/bx。闲话:在我看过的所有人的做题过程中,大家都不约而同的把棋子数量相同时答案相同当作了第一发(。但是很可惜,这个结论是错误的。样例已经给出了当棋子数量为\(2\)的答案,在此我们略去讨论。对于棋子数量为\(1\)答案也很明显是后手......
  • (2023.12.18)wifi的频宽配置
    //网关设备上的WiFi问题单ht_capab:频宽可调HighThroughput高吞吐量能力参数VHT:VeryHighThroughput现在也叫WiFi5GuardInterval:保护间隔(无线提速参数)AX2和AX5:指的是2.4G频段和5G频段HT40+:次通道高于主通道HT40-:次通道低于主通道SHORT-GI-20:disabledifnotsetWPA2:体......
  • 参会指南 |WAIC 2023零数科技产业区块链生态论坛专业观众线下参会指引
    2023年7月7日(周五)13:00-17:00,由赛迪区块链研究院指导,上海零数科技有限公司主办的“数实融合,智领未来”产业区块链生态论坛,将于上海世博中心518会议室举行。论坛拟邀政府领导、院士学者、企业代表等重磅嘉宾,聚焦区块链赋能产业创新变革与实践应用,推动数字经济与实体经济深度融合。线......
  • 2023 年活力开源贡献者、开源项目揭晓|JeecgBoot 成功入选
    JeecgBoot是一个开源的企业级快速开发平台,它成功入选2023年度生态开源项目,这是对其十年坚持开源的实至名归的认可。作为一个开源项目,JeecgBoot在过去的十年里一直秉承着开放、共享、协作的理念,不断推动着开源社区的发展。其成功入选2023年度生态开源项目,无疑是对其在开源领......
  • 2023.12 English四级 作文
    《2023年12月英语四级作文真题及范文(三套全)》最深刻的一次校园活动作文1Supposeyouruniversitynewspaperisinvitingsubmissionsfromstudentsforitscomingeditiononacampuseventthathasimpressedthemmost.LastSaturday,ourStudentU......
  • 2023.12 六级 English 作文
    《2023年12月英语六级作文真题及范文网络版(三套全)》作文1:TheimportanceofacquiringthebasicknowledgeAsweallknow,masteringgoodbasicknowledgeisanimportantstepthateverystudentmustgothroughinthelearningprocess,anditiscrucial......