第十九届全国大学生信息安全竞赛(ciscn)暨第三届长城杯网数智安全大赛—初赛WriteUp

admin 2026-01-01 05:09:36 网络安全文章 来源:ZONE.CI 全球网 0 阅读模式

文章总结: 本文概述第十九届CISCN初赛WriteUp,包含ECDSA、EzFlag及RSA_NestingDoll三题。作者通过私钥计算、逆向斐波那契生成逻辑及改进Pollardp-1算法分别解出Flag。文章提供了完整的Python解题脚本与核心算法分析,展示了密码学计算与二进制分析技术在CTF实战中的应用,具有较高的技术参考价值。 综合评分: 95 文章分类: CTF,逆向分析


cover_image

第十九届全国大学生信息安全竞赛(ciscn)暨第三届长城杯网数智安全大赛—初赛WriteUp

Pirater

2025年12月31日 16:01 广东

以下文章来源于Overf1ow ,作者Overf1ow

Overf1ow .

Overf1ow安全团队,不定期更新国内外赛事WP。 官方网站:overf1ow.aristore.top

又一届ciscn,然而这是我们第一次国赛,排在第450名。今年已进入尾声,感谢这一年师傅们对Overf1ow的关注_(•̀ω•́ 」∠)_即将迎来2026,提前祝各位师傅新年快乐!

密码学

ECDSA

题目开头就给私钥了,只需要将代码重新输入计算就行:

from ecdsa import SigningKey, NIST521p
from hashlib import sha512, md5

digest_int = int.from_bytes(sha512(b"Welcome to this challenge!").digest(), "big")
curve_order = NIST521p.order
priv_int = digest_int % curve_order

flag = "flag{" + md5(str(priv_int).encode()).hexdigest() + "}"
print(flag)
flag{581bdf717b780c3cd8282e5a4d50f3a0}

EzFlag

首先放到ida查看程序执行流程:程序首先读取用户输入,并与字符串 “V3ryStr0ngp@ssw0rd” 进行比较,这一步是校验,但Flag的生成逻辑其实在验证通过后的代码块中,

程序初始化变量v11=1。进入一个32次的循环(i从0到31)。每次循环调用函数 f(v11) 获取一个字符。在索引为7,12,17,22的位置插入连字符-。每次循环结束前,更新v11的值v11=v11*8+i+64。

跟进函数f(地址0x1229),分析其逻辑:该函数实现了一个模16的斐波那契数列生成器。它计算斐波那契数列的第v11 项,并在每一步加法后进行&0xF(即模16)操作。最终结果作为索引,从全局字符串K中取值。通过交叉引用或查看数据段,找到全局字符串K的内容为:”012ab9c3478d56ef”。重点就是64位整数溢出截断,还有一个就是如果不手动模拟64位截断,v11会变成一个巨大的数,所以这里也要注意。

exp:

def get_fib_mod16(n):
    n = n % 24
    if n == 0: return0
    if n == 1: return1

    a, b = 0, 1
    for _ in range(2, n + 1):
        a, b = b, (a + b) % 16
    return b

def solve():
    K = "012ab9c3478d56ef"
    v11 = 1
    flag_content = ""

    for i in range(32):
        idx = get_fib_mod16(v11)

        char = K[idx]
        flag_content += char

        if i in [7, 12, 17, 22]:
            flag_content += "-"

        v11 = (v11 * 8 + i + 64) & 0xFFFFFFFFFFFFFFFF

    print(f"flag{{{flag_content}}}")

solve()
flag{10632674-1d219-09f29-14769-f60219a24}

RSA_NestingDoll

题目本身并不难理解,nn1的每个因子满足:p=a*p1+1。其中a是2**20以内随机选取的素数的乘积。 和Pollard p-1很像,可以先了解一下原理:https://www.cnblogs.com/chen-xing-zzu/p/18528441。 对于本题来说,我们可以利用上B的取值范围和n1的值,在原本的分解方法之上再做两件事情:

  • 让pows所选取的素数小于
  • 再用pows乘上n1,一是依旧满足费马小定理,二是由于大因子的存在,仅仅用pows并不足以分解n

脚本如下:

from Crypto.Util.number import *
from gmpy2 import *
from sympy import prod, primefactors
import random

def prime_powers(B):
    sieve_list = list(sieve_base)
    whileTrue:
        new_sieve = int(next_prime(sieve_list[-1]))
        if new_sieve > B:
            break
        sieve_list.append(new_sieve)

    out = []
    for p in sieve_list:
        pk = p
&nbsp; &nbsp; &nbsp; &nbsp;&nbsp;while&nbsp;pk * p <= B:
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; pk *= p
&nbsp; &nbsp; &nbsp; &nbsp; out.append(pk)
&nbsp; &nbsp;&nbsp;return&nbsp;out

def&nbsp;Pollard_improve(n, n1, pows, chunk_size):
&nbsp; &nbsp; print(f"factoring...")
&nbsp; &nbsp; factors = []
&nbsp; &nbsp;&nbsp;whileTrue:
&nbsp; &nbsp; &nbsp; &nbsp; x = random.randint(2, n -&nbsp;1)

&nbsp; &nbsp; &nbsp; &nbsp;&nbsp;for&nbsp;i&nbsp;in&nbsp;range(0, len(pows), chunk_size):
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; chunk = pows[i : i + chunk_size]
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; E = int(prod(chunk))&nbsp;# 将pow乘起来,寻找p可能会更快,但有很大概率找不到
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; a = x
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; x = powmod(a, E, n)
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; y = powmod(x, n1, n)
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; fac = gcd(y -&nbsp;1, n)

&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;&nbsp;if1&nbsp;< fac < n:
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; factors.append(int(fac))
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; n //= fac
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; print(f"find the&nbsp;{len(factors)}-th factor:&nbsp;{fac}")
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;&nbsp;break

&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;&nbsp;if&nbsp;fac == n:
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;&nbsp;for&nbsp;p&nbsp;in&nbsp;chunk:
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; x = pow(a, p, n)&nbsp;# 如果用乘积的方法找不到,就挨个寻找
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; y = pow(x, n1, n)
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; fac = gcd(y -&nbsp;1, n)
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;&nbsp;if1&nbsp;< fac < n:
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; factors.append(int(fac))
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; n //= fac
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; print(f"find the&nbsp;{len(factors)}-th factor:&nbsp;{fac}")
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;&nbsp;break

&nbsp; &nbsp; &nbsp; &nbsp;&nbsp;if&nbsp;is_prime(n):
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; factors.append(int(n))
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; print(f"find the&nbsp;{len(factors)}-th factor:&nbsp;{n}")
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;&nbsp;return&nbsp;factors

n1 =&nbsp;16141229822582999941795528434053604024130834376743380417543848154510567941426284503974843508505293632858944676904777719167211264225017879544879766461905421764911145115313698529148118556481569662427943129906246669392285465962009760415398277861235401144473728421924300182818519451863668543279964773812681294700932779276119980976088388578080667457572761731749115242478798767995746571783659904107470270861418250270529189065684265364754871076595202944616294213418165898411332609375456093386942710433731450591144173543437880652898520275020008888364820928962186107055633582315448537508963579549702813766809204496344017389879
n =&nbsp;484831124108275939341366810506193994531550055695853253298115538101629337644848848341479419438032232339003236906071864005366050185096955712484824249228197577223248353640366078747360090084446361275032026781246854700074896711976487694783856878403247312312487197243272330518861346981470353394149785086635163868023866817552387681890963052199983782800993485245670437818180617561464964987316161927118605512017355921555464359512280368738197370963036482455976503266489446554327046948670215814974461717020804892983665655107351050779151227099827044949961517305345415735355361979690945791766389892262659146088374064423340675969505766640604405056526597458482705651442368165084488267428304515239897907407899916127394598273176618290300112450670040922567688605072749116061905175316975711341960774150260004939250949738836358264952590189482518415728072191137713935386026127881564386427069721229262845412925923228235712893710368875996153516581760868562584742909664286792076869106489090142359608727406720798822550560161176676501888507397207863998129261472631954482761264406483807145805232317147769145985955267206369675711834485845321043623959730914679051434102698588945009836642922614296598336035078421463808774940679339890140690147375340294139027290793
c =&nbsp;657984921229942454933933403447729006306657607710326864301226455143743298424203173231485254106370042482797921667656700155904329772383820736458855765136793243316671212869426397954684784861721375098512569633961083815312918123032774700110069081262242921985864796328969423527821139281310369981972743866271594590344539579191695406770264993187783060116166611986577690957583312376226071223036478908520539670631359415937784254986105845218988574365136837803183282535335170744088822352494742132919629693849729766426397683869482842748401000853783134170305075124230522253670782186531697976487673160305610021244587265868919495629
B =&nbsp;2**20
e =&nbsp;65537

prime_power = prime_powers(B)
n_factors = Pollard_improve(n, n1, prime_power,&nbsp;5000)&nbsp;# 不必一次性用上所有power,给个限定范围能更快
n1_factors = [primefactors(p -&nbsp;1)[-1]&nbsp;for&nbsp;p&nbsp;in&nbsp;n_factors]

phi = prod([p1 -&nbsp;1for&nbsp;p1&nbsp;in&nbsp;n1_factors])
d = inverse(e, phi)
m = pow(c,d,n1)
flag = long_to_bytes(m)
print(flag)
flag{fak3_r5a_0f_euler_ph1_of_RSA_040a2d35}

免责声明:

本文所载程序、技术方法仅面向合法合规的安全研究与教学场景,旨在提升网络安全防护能力,具有明确的技术研究属性。

任何单位或个人未经授权,将本文内容用于攻击、破坏等非法用途的,由此引发的全部法律责任、民事赔偿及连带责任,均由行为人独立承担,本站不承担任何连带责任。

本站内容均为技术交流与知识分享目的发布,若存在版权侵权或其他异议,请通过邮件联系处理,具体联系方式可点击页面上方的联系我

本文转载自:Pirater 《第十九届全国大学生信息安全竞赛(ciscn)暨第三届长城杯网数智安全大赛—初赛WriteUp》

评论:0   参与:  0