Contents

春秋杯冬季赛2024_crypto

前言

报名了,但是没打,刚回家,就被亲戚拉过去串门了,然后中间还有一天西湖论剑,害

题目

通往哈希的旅程

题目内容: 在数字城,大家都是通过是通过数字电话进行的通信,常见是以188开头的11位纯血号码组成,亚历山大抵在一个特殊的地方截获一串特殊的字符串"ca12fd8250972ec363a16593356abb1f3cf3a16d",通过查阅发现这个跟以前散落的国度有点相似,可能是去往哈希国度的。年轻程序员亚力山大抵对这个国度充满好奇,决定破译这个哈希值。在经过一段时间的摸索后,亚力山大抵凭借强大的编程实力成功破解,在输入对应字符串后瞬间被传送到一个奇幻的数据世界,同时亚力山大抵也开始了他的进修之路。(提交格式:flag{11位号码}) 即已知前三位,爆破八位,好像cmd5已经有了

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
import hashlib

def crack_hash(target_hash):
    prefix = "188"
    for num in range(100000000): 
        phone_number = prefix + f"{num:08d}"
        generated_hash = hashlib.sha1(phone_number.encode()).hexdigest()
        if generated_hash == target_hash:
            return phone_number
    return None
target_hash = "ca12fd8250972ec363a16593356abb1f3cf3a16d"

result = crack_hash(target_hash)

if result:
    print(f"破解成功!电话号码为:flag{{{result}}}")
else:
    print("破解失败,未找到匹配的号码。")

你是小哈斯?

题目内容: 年轻黑客小符参加CTF大赛,他发现这个小哈斯文件的内容存在高度规律性,并且文件名中有隐藏信息,他成功找到了隐藏的信息,并破解了挑战。得意地说:“成功在于探索与质疑,碰撞是发现真相的关键!” 一个一个映射过去,sha256,sha1,md5都试一下,发现是sha1,结果好像可以从160bits看出来这是sha1

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
import hashlib
import string

def attack(h):
    table = string.ascii_letters + string.digits + "!@#$%^&*()_+-=[]{}|;:,.<>?/~`"
    for m in table:
        if hashlib.sha1(m.encode()).hexdigest() == h:
            return m
    return None  

data = open('chall.txt', 'r').readlines()
hashes = []
for i in data:
    hashes.append(i.strip())

table = {}
for i in hashes:
    table[i] = attack(i)

m = ""
for i in hashes:
    if table[i] is not None: 
        m += table[i]

print(m)

RSA1

task

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
from Crypto.Util.number import *
import uuid


p, q = [getPrime(512) for _ in range(2)]
N = p * q

flag = b'flag{' + str(uuid.uuid4()).encode() + b'}'
flag += bin(getPrime((1024 - bytes_to_long(flag).bit_length()) // 8)).encode()

m1 = bytes_to_long(flag)
m2 = bytes_to_long(''.join(chr((ord(i) + 3) % 128) for i in flag.decode()).encode())

e = getPrime(128)
c1 = pow(m1 * e, 2835, N)
c2 = pow(m2, 2025, N)
c3 = pow(m2, 2835, N) + e

print(f'{N = }')
print(f'{c1 = }')
print(f'{c2 = }')
print(f'{c3 = }')

'''
N = 176871561120476589165761750300633332586877708342448994506175624203633860119621512318321172927876389631918300184221082317741380365447197777026256405312212716630617721606918066048995683899616059388173629437673018386590043053146712870572300799479269947118251011967950970286626852935438101046112260915112568392601
c1 = 47280375006817082521114885578132104427687384457963920263778661542552259860890075321953563867658233347930121507835612417278438979006705016537596357679038471176957659834155694284364682759675841808209812316094965393550509913984888849945421092463842546631228640293794745005338773574343676100121000764021207044019
c2 = 176231410933979134585886078013933649498379873444851943224935010972452769899603364686158279269197891190643725008151812150428808550310587709008683339436590112802756767140102136304346001599401670291938369014436170693864034099138767167055456635760196888578642643971920733784690410395944410255241615897032471127315
c3 = 135594807884016971356816423169128168727346102408490289623885211179619571354105102393658249292333179346497415129785184654008299725617668655640857318063992703265407162085178885733134590524577996093366819328960462500124201402816244104477018279673183368074374836717994805448310223434099196774685324616523478136309
'''

首先e是可以利用c2,c3多项式直接求出来的,后面部分有点类似日本的那个rot13了,但是更简单,差值不用自己手算,直接生成m1和m2减一下就好了,然后就是hgcd的富兰克林

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
N = 176871561120476589165761750300633332586877708342448994506175624203633860119621512318321172927876389631918300184221082317741380365447197777026256405312212716630617721606918066048995683899616059388173629437673018386590043053146712870572300799479269947118251011967950970286626852935438101046112260915112568392601
c1 = 47280375006817082521114885578132104427687384457963920263778661542552259860890075321953563867658233347930121507835612417278438979006705016537596357679038471176957659834155694284364682759675841808209812316094965393550509913984888849945421092463842546631228640293794745005338773574343676100121000764021207044019
c2 = 176231410933979134585886078013933649498379873444851943224935010972452769899603364686158279269197891190643725008151812150428808550310587709008683339436590112802756767140102136304346001599401670291938369014436170693864034099138767167055456635760196888578642643971920733784690410395944410255241615897032471127315
c3 = 135594807884016971356816423169128168727346102408490289623885211179619571354105102393658249292333179346497415129785184654008299725617668655640857318063992703265407162085178885733134590524577996093366819328960462500124201402816244104477018279673183368074374836717994805448310223434099196774685324616523478136309

from Crypto.Util.number import *
import sys
'''PR.<x> = PolynomialRing(Zmod(N))

f=(c3-x)^5-(c2)^7
res=f.monic().small_roots(X=2^128,beta=0.4,epsilon=0.02)
print(res)

'''

'''from Crypto.Util.number import *
import uuid
flag = b'flag{' + str(uuid.uuid4()).encode() + b'}'
flag += bin(getPrime((1024 - bytes_to_long(flag).bit_length()) // 8)).encode()

m1 = bytes_to_long(flag)
m2 = bytes_to_long(''.join(chr((ord(i) + 3) % 128) for i in flag.decode()).encode())
print(m2-m1)'''

e=281211879955223558268422413173406510291
b=138604255630984394504644405862999441108691457990544710059664868220625513430462483763119797291779992529360824019886958759717736876661453044335745573603330761817432828924688993026332102549607397901351619425324993583087500714061523945925857368498922102768458574857510324727265052999967460998294909713988129273348867

def HGCD(a, b):
    if 2 * b.degree() <= a.degree() or a.degree() == 1:
        return 1, 0, 0, 1
    m = a.degree() // 2
    a_top, a_bot = a.quo_rem(x^m)
    b_top, b_bot = b.quo_rem(x^m)
    R00, R01, R10, R11 = HGCD(a_top, b_top)
    c = R00 * a + R01 * b
    d = R10 * a + R11 * b
    q, e = c.quo_rem(d)
    d_top, d_bot = d.quo_rem(x^(m // 2))
    e_top, e_bot = e.quo_rem(x^(m // 2))
    S00, S01, S10, S11 = HGCD(d_top, e_top)
    RET00 = S01 * R00 + (S00 - q * S01) * R10
    RET01 = S01 * R01 + (S00 - q * S01) * R11
    RET10 = S11 * R00 + (S10 - q * S11) * R10
    RET11 = S11 * R01 + (S10 - q * S11) * R11
    return RET00, RET01, RET10, RET11

def GCD(a, b):
    print(a.degree(), b.degree())
    q, r = a.quo_rem(b)
    if r == 0:
        return b
    R00, R01, R10, R11 = HGCD(a, b)
    c = R00 * a + R01 * b
    d = R10 * a + R11 * b
    if d == 0:
        return c.monic()
    q, r = c.quo_rem(d)
    if r == 0:
        return d
    return GCD(d, r)

sys.setrecursionlimit(500000)

R.<x> = PolynomialRing(Zmod(N))
f = (x*e)^2835 - c1
g = (x+b)^2025 - c2

res = GCD(f,g)
m=int(-res.monic().coefficients()[0])

for i in range(2^20):
    mm=m+i*N
    if b'flag{' in long_to_bytes(mm):
        print(long_to_bytes(mm))

factor

task

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
import random
import os
from Crypto.Util.number import *
from secret import flag


def pad(x, n):
    while len(x) < n // 8:
        x += os.urandom(1)
    return x


def genp(p, l):
    while 1:
        r = random.randint(1 << l - 1, 1 << l)
        if isPrime(p + r):
            return p + r


bits = 1024
b = 345
flag = pad(flag, bits * 3)
m = bytes_to_long(flag)
p = getPrime(bits)
q = genp(p, b)
r = genp(q, b)
n = p * q * r
print(n)
print(pow(m, 65537, n))
# 5605777780127871552103278440489930168557569118966981388111283042550796167470265465148458919374665519335013101681890408413810351780671950283765145543168779446153786190869731166707967097095246677053262868926963631796027692694223765625053269102325714361312299011876036815423751522482629914361369303649193526946050137701205931577449326939722902280884984494828850611521784382097900268639648421100760612558110614208245291400961758972415881709281708443424129033685255718996719201537066717587527029554871540574867831957154286334639399985379381455084604901293000229526196544921067214723085504463673412082637877637982771445298815007769526806112008703908400170846707986989384244531990469279604588770393462375930699135443458952703826608237292999895910024613311408883134789788541751697007502656798556053417265191533053158952284994030769145926816478390761642058013769635850833893158830591398862163134753203291719549474871116653745337968227
# 2998195560453407057321637509862236387961676411996988529185696118404592349869917006166370346762261303282478779647282039317061146533808487789458703169149689179547543732935053220010550004328207373171271534689897340156346458951776319267981966893926724550629182100766890856964207263709029611781806548130358294543573874132473259788387939849997550651614987993962540192023207354839106090274252125961835070701748643163379053118598595995782448140944376681636633592442158453965800439960134688017496184195454406927204485213436540382637720118180670197194949275760000729877093621741313147190401896114633643891311672542703928421032698499968701052818985292683628072129271790220674145955527935027879112279336148316425115255710066132502392447843608711463775710558880259205308541126041959858947252063815158749021817255637836170676726466347847422352280599210078359786387419424076245960344657767332883964636288493649066530215094453490169688507988

三元copper,pqr接近,直接把n开三次根号

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
import itertools
from Crypto.Util.number import *
import gmpy2
from tqdm import trange
def small_roots(f, bounds, m=1, d=None):
    if not d:
        d = f.degree()

    R = f.base_ring()
    N = R.cardinality() #取得模数



    f /= f.coefficients().pop(0) #最高次项系数化为0,coefficients是多项式的降次幂排列系数
    f = f.change_ring(ZZ)

    G = Sequence([], f.parent())

    for i in range(m + 1):
        base = N ^ (m - i) * f ^ i #收集基多项式

        for shifts in itertools.product(range(d), repeat=f.nvariables()):
            g = base * prod(map(power, f.variables(), shifts))
            G.append(g)
    print(G)
    B, monomials = G.coefficient_matrix()
    monomials = vector(monomials)

    factors = [monomial(*bounds) for monomial in monomials]
    for i, factor in enumerate(factors):
        B.rescale_col(i, factor)

    B = B.dense_matrix().LLL()

    B = B.change_ring(QQ)
    for i, factor in enumerate(factors):
        B.rescale_col(i, 1 / factor)

    H = Sequence([], f.parent().change_ring(QQ))
    for h in filter(None, B * monomials):
        H.append(h)
        I = H.ideal()
        if I.dimension() == -1:
            H.pop()
        elif I.dimension() == 0:
            roots = []
            for root in I.variety(ring=ZZ):
                root = tuple(R(root[var]) for var in f.variables())
                roots.append(root)
            return roots
    return []
n=5605777780127871552103278440489930168557569118966981388111283042550796167470265465148458919374665519335013101681890408413810351780671950283765145543168779446153786190869731166707967097095246677053262868926963631796027692694223765625053269102325714361312299011876036815423751522482629914361369303649193526946050137701205931577449326939722902280884984494828850611521784382097900268639648421100760612558110614208245291400961758972415881709281708443424129033685255718996719201537066717587527029554871540574867831957154286334639399985379381455084604901293000229526196544921067214723085504463673412082637877637982771445298815007769526806112008703908400170846707986989384244531990469279604588770393462375930699135443458952703826608237292999895910024613311408883134789788541751697007502656798556053417265191533053158952284994030769145926816478390761642058013769635850833893158830591398862163134753203291719549474871116653745337968227

R.<x,y,z>=Zmod(n)[]
n_ = int(gmpy2.iroot(n, 3)[0])
t = 2 ^ 3
P = []
for i in trange(t):
    for j in range(t):
        for k in range(t):
            f = (n_ + t * x + i) * (n_ + t * y + j) * (n_ + t * z + k)
            s = 342
            roots = small_roots(f, [2 ^ s, 2 ^ s, 2 ^ s], m=1, d=3)
            if roots:
                a, b, c = [int(ii) * t + jj if int(ii).bit_length() <= 512 else int(n - ii) * t - jj for ii, jj in zip(roots[0], [i, j, k])]
                for l in [a, b, c]:
                    p = n_ + l
                    if n % p == 0:
                        P.append(p)
                    p = n_ - l
                    if n % p == 0:
                        P.append(p)
p, q, r = set(P)
d = inverse(65537, (p - 1) * (q - 1) * (r - 1))
c=2998195560453407057321637509862236387961676411996988529185696118404592349869917006166370346762261303282478779647282039317061146533808487789458703169149689179547543732935053220010550004328207373171271534689897340156346458951776319267981966893926724550629182100766890856964207263709029611781806548130358294543573874132473259788387939849997550651614987993962540192023207354839106090274252125961835070701748643163379053118598595995782448140944376681636633592442158453965800439960134688017496184195454406927204485213436540382637720118180670197194949275760000729877093621741313147190401896114633643891311672542703928421032698499968701052818985292683628072129271790220674145955527935027879112279336148316425115255710066132502392447843608711463775710558880259205308541126041959858947252063815158749021817255637836170676726466347847422352280599210078359786387419424076245960344657767332883964636288493649066530215094453490169688507988

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

funny_rsa

task

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
import random
import libnum
from Crypto.Util.number import bytes_to_long, long_to_bytes

print("Welcome to ChunqiuCTF Game!")
print("接下来完成下面的挑战")
print("Good luck!")

# funny
hint = b' '
m = b' '
p = libnum.generate_prime(1024)
q = libnum.generate_prime(1024)
n = p * q

print("give you some funny numbers")
# funny 1
print(p+q - p*q + random.randint(-1025, +1025)) 
# funny 2
print(bytes_to_long(m)*bytes_to_long(hint))
# funny 3
print(bytes_to_long(m)*n*bytes_to_long(hint) - 1025)
# funny 4
print(pow(bytes_to_long(hint), 65537, n))




a=-17696257697673533517695215344482784803953262308315416688683426036407670627060768442028628137969719289734388098357659521255966031131390425549974547376165392147394271974280020234101031837837842620775164967619688351222631803585213762205793801828461058523503457022704948803795360591719481537859524689187847958423587638744086265395438163720708785636319741908901866136858161996560525252461619641697255819255661269266471689541673348377717503957328827459396677344554172542244540931545166846117626585580964318010181586516365891413041095399344533013057011854734701706641516027767197631044458866554524544179750101814734153116374
b=23686728880494758233026798487859622755203105120130180108222733038275788082047755828771429849079142070779731875136837978862880500205129022165600511611807590195341629179443057553694284913974985006590617143873019530710952420242412437467917519539591683898715990297750494900923245055632544763410401540518654522017115269508183482044872091052235608170710105631742176900306097734799793264202179181242015892763311753674799273300604804820015447161950996038795518844564861004398396796284113803759208011
c=419166458284161364374927086939132546372091965414091344286510440034452974193054721041229068769658972346759176374539266235862042787888391905466876330331208651698002159575012622762558316612596034044109738533275009086940744966244759977014078484433213617582101347769476703012517531619023366639507114909172774156647998737369356116119513795863130218094614475699956104117183821832339358478426978211282822163928764161915824622224165694904342224081321345691796882691318330781141960650263488927837990954860719950761728580780956673732592771855694502630374907978111094148614378212006604233062606116168868545120407836000858982789824582335703891535021579560434875457656655941164757860852341484554015214879991896412137447010444797452119431147303295803678311972500421396900616845556636124424993090559354406417222700637726789045926994792374756038517484548544506630672251868349748176389591615802039026216656891403871728516658502023897343287181822303758976641229952646993446276281728919020747050486979968215989594984778920359425264076558022228448529089047021814759587052098774273578311709416672952218680244714492318709603579024
d=13541898381047120826573743874105965191304100799517820464813250201030319771155430755606644860103469823030581858410957600027665504533335597988508084284252510961847999525811558651340906333101248760970154440885012717108131962658921396549020943832983712611749095468180648011521808106480590665594160479324931351996812185581193608244652792936715504284312172734662364676167010674359243219959129435127950232321130725013160026977752389409620674167037650367196748592335698164875097139931376389630867192761783936757260359606379088577977154378217235326249540098268616890307702288393952949444753648206049856544634755301197410481479

神人题目,求出后是fakeflag,把里面的数拉出来再转一下

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
b=23686728880494758233026798487859622755203105120130180108222733038275788082047755828771429849079142070779731875136837978862880500205129022165600511611807590195341629179443057553694284913974985006590617143873019530710952420242412437467917519539591683898715990297750494900923245055632544763410401540518654522017115269508183482044872091052235608170710105631742176900306097734799793264202179181242015892763311753674799273300604804820015447161950996038795518844564861004398396796284113803759208011
c=419166458284161364374927086939132546372091965414091344286510440034452974193054721041229068769658972346759176374539266235862042787888391905466876330331208651698002159575012622762558316612596034044109738533275009086940744966244759977014078484433213617582101347769476703012517531619023366639507114909172774156647998737369356116119513795863130218094614475699956104117183821832339358478426978211282822163928764161915824622224165694904342224081321345691796882691318330781141960650263488927837990954860719950761728580780956673732592771855694502630374907978111094148614378212006604233062606116168868545120407836000858982789824582335703891535021579560434875457656655941164757860852341484554015214879991896412137447010444797452119431147303295803678311972500421396900616845556636124424993090559354406417222700637726789045926994792374756038517484548544506630672251868349748176389591615802039026216656891403871728516658502023897343287181822303758976641229952646993446276281728919020747050486979968215989594984778920359425264076558022228448529089047021814759587052098774273578311709416672952218680244714492318709603579024

a=-17696257697673533517695215344482784803953262308315416688683426036407670627060768442028628137969719289734388098357659521255966031131390425549974547376165392147394271974280020234101031837837842620775164967619688351222631803585213762205793801828461058523503457022704948803795360591719481537859524689187847958423587638744086265395438163720708785636319741908901866136858161996560525252461619641697255819255661269266471689541673348377717503957328827459396677344554172542244540931545166846117626585580964318010181586516365891413041095399344533013057011854734701706641516027767197631044458866554524544179750101814734153116374
cc=13541898381047120826573743874105965191304100799517820464813250201030319771155430755606644860103469823030581858410957600027665504533335597988508084284252510961847999525811558651340906333101248760970154440885012717108131962658921396549020943832983712611749095468180648011521808106480590665594160479324931351996812185581193608244652792936715504284312172734662364676167010674359243219959129435127950232321130725013160026977752389409620674167037650367196748592335698164875097139931376389630867192761783936757260359606379088577977154378217235326249540098268616890307702288393952949444753648206049856544634755301197410481479
n=17696257697673533517695215344482784803953262308315416688683426036407670627060768442028628137969719289734388098357659521255966031131390425549974547376165392147394271974280020234101031837837842620775164967619688351222631803585213762205793801828461058523503457022704948803795360591719481537859524689187847958423854887927385251366355690432834992251981467618044652729026583095120137339494261578444395436053118572869777876188550962458760967380393115254438861483654205295921877587647313478227890321887337600538927105776831391301452172833129470417556416145729275237684471317547282356386364496954995277114788157853037049373459

'''
a=p+q - n+ random.randint(-1025, +1025)
-a=n-p-q+k
phi=(p-1)*(q-1)=n-p-q+1=-a-k+1
'''
from Crypto.Util.number import *

for k in range(-1026,1026):
    phi=-a+k+1
    e=65537
    d=inverse(e,phi)
    hint=pow(cc,d,n)
    m=b//hint
    flag=long_to_bytes(m)
    if b'flag{' in flag:
        print(flag)
        print(k)
        break

EZ_rsa

task

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
from secret import flag
from Crypto.Util.number import *
import hashlib


p = getPrime(512)
q = getPrime(512)
N = p * q
e = getPrime(1023)
assert e < N
c = pow(bytes_to_long(flag), e, N)

print(f'{N = }')
print(f'{e = }')
print(f'{c = }')

phi = (p - 1) * (q - 1)
d = inverse(e, phi)
k = (e * d - 1) // phi

dh = d >> 234
dl = d % pow(2, 24)
kh = k >> 999

hash224 = bytes_to_long(hashlib.sha224(long_to_bytes(dl)).digest())
hash512 = bytes_to_long(hashlib.sha512(long_to_bytes(kh)).digest())
leak = hash224 ^ hash512 ^ (k % pow(2, 512))

print(f'{dh = }')
print(f'{leak = }')

'''
N = 136118062754183389745310564810647775266982676548047737735816992637554134173584848603639466464742356367710495866667096829923708012429655117288119142397966759435369796296519879851106832954992705045187415658986211525671137762731976849094686834222367125196467449367851805003704233320272315754132109804930069754909
e = 84535510470616870286532166161640751551050308780129888352717168230068335698416787047431513418926383858925725335047735841034775106751946839596675772454042961048327194226031173378872580065568452305222770543163564100989527239870852223343451888139802496983605150231009547594049003160603704776585654802288319835839
c = 33745401996968966125635182001303085430914839302716417610841429593849273978442350942630172006035442091942958947937532529202276212995044284510510725187795271653040111323072540459883317296470560328421002809817807686065821857470217309420073434521024668676234556811305412689715656908592843647993803972375716032906
dh = 4640688526301435859021440727129799022671839221457908177477494774081091121794107526784960489513468813917071906410636566370999080603260865728323300663211132743906763686754869052054190200779414682351769446970834390388398743976589588812203933
leak = 12097621642342138576471965047192766550499613568690540866008318074007729495429051811080620384167050353010748708981244471992693663360941733033307618896919023
'''

和su的类似,先拿到k高位,然后通过d去求出完整的k,p+q=N+1-K**(-1) mod e,e是1023bits,就是完整的p+q了

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
from Crypto.Util.number import*
import hashlib
from tqdm import trange

n = 136118062754183389745310564810647775266982676548047737735816992637554134173584848603639466464742356367710495866667096829923708012429655117288119142397966759435369796296519879851106832954992705045187415658986211525671137762731976849094686834222367125196467449367851805003704233320272315754132109804930069754909
e = 84535510470616870286532166161640751551050308780129888352717168230068335698416787047431513418926383858925725335047735841034775106751946839596675772454042961048327194226031173378872580065568452305222770543163564100989527239870852223343451888139802496983605150231009547594049003160603704776585654802288319835839
c = 33745401996968966125635182001303085430914839302716417610841429593849273978442350942630172006035442091942958947937532529202276212995044284510510725187795271653040111323072540459883317296470560328421002809817807686065821857470217309420073434521024668676234556811305412689715656908592843647993803972375716032906
dh = 4640688526301435859021440727129799022671839221457908177477494774081091121794107526784960489513468813917071906410636566370999080603260865728323300663211132743906763686754869052054190200779414682351769446970834390388398743976589588812203933
leak = 12097621642342138576471965047192766550499613568690540866008318074007729495429051811080620384167050353010748708981244471992693663360941733033307618896919023

dh=dh<<234
k_=(e*dh-1)//n
kh=k_>>999
khh=k_>>512
khh+=1
khh=khh<<512

hash512=bytes_to_long(hashlib.sha512(long_to_bytes(kh)).digest())

def findpq(range):
    low=range[0]
    high=range[1]
    for dl in trange(low,high):
        hash224=bytes_to_long(hashlib.sha224(long_to_bytes(dl)).digest())
        kl=leak^^hash224^^hash512
        k=khh+kl
        kinv=inverse(k,e)
        s=(n+1+kinv)%e
        if 511<=int(s).bit_length()<=515:
            var('p,q')
            eq1=p+q==s
            eq2=p*q==n
            res=solve([eq1,eq2],[p,q])
            print(res)
            break

ranges=[(i,i+524288) for i in range(0,2^24,524288)]
from multiprocessing import Pool
with Pool(32) as pool:
    r=list(pool.imap(findpq,ranges))

from Crypto.Util.number import*
N=
13611806275418338974531056481064777526698267654804773773581699263755413417358484860363
94664647423563677104958666670968299237080124296551172881191423979667594353697962965198
79851106832954992705045187415658986211525671137762731976849094686834222367125196467449
367851805003704233320272315754132109804930069754909
e=
84535510470616870286532166161640751551050308780129888352717168230068335698416787047431
51341892638385892572533504773584103477510675194683959667577245404296104832719422603117
33788725800655684523052227705431635641009895272398708522233434518881398024969836051502
31009547594049003160603704776585654802288319835839
c=
33745401996968966125635182001303085430914839302716417610841429593849273978442350942630
17200603544209194295894793753252920227621299504428451051072518779527165304011132307254
04598833172964705603284210028098178076860658218574702173094200734345210246686762345568
11305412689715656908592843647993803972375716032906
p=
10934414478852797568005414763571686360760867378628976989236829057638353964927471283010
377997441905099315104229539011544913211044674190339201843041130109737
q= N//p
d= inverse(e,(p-1)*(q-1))
m= pow(c,d,N)
print(long_to_bytes(m))

running

task

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
from Crypto.Cipher import AES
from Crypto.Util.Padding import pad
from hashlib import md5
from secret import flag

K=5
p=[2, 3, 5, 7, 11, 13, 17, 19, 23, 29, 31, 37, 41]
while i:=i+1:
    if all([0,i][sum([0,j][i%j==0]for j in range(1,i+1))>2*i]%j for j in p[:K]):print(AES.new(key=md5(str(i).encode()).digest(),mode=AES.MODE_ECB).encrypt(pad(flag,16)));break
# b'y.\x86k\xbd\xbfd7)\xcdHm\xf7\x1e\xfdX\xf6z\xb0\xd5XD}\xe8m\x81D\x84\x1c\xa0<\x1f\xd0f\x9f\xcc\x89\r\xc4\x9d\xadbY\xa3\xb1\x1d5?'

Abundant Numbers的丰度5,直接看论文,把里面的数据一个一个试 https://projecteuclid.org/journals/bulletin-of-the-belgian-mathematical-society-simon-stevin/volume-12/issue-1/On-the-smallest-abundant-number-not-divisible-by-the-first/10.36045/bbms/1113318127.full?tab=ArticleFirstPage

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
c=b'y.\x86k\xbd\xbfd7)\xcdHm\xf7\x1e\xfdX\xf6z\xb0\xd5XD}\xe8m\x81D\x84\x1c\xa0<\x1f\xd0f\x9f\xcc\x89\r\xc4\x9d\xadbY\xa3\xb1\x1d5?'
from Crypto.Cipher import AES
from Crypto.Util.Padding import pad
from hashlib import md5
from Crypto.Util.number import *

primes=[]

for i in range(350):
    if isPrime(i):
        primes.append(i)

k=17**2*19**2*23**2

for i in primes[9:]:
    k*=i

flag=AES.new(key=md5(str(k).encode()).digest(),mode=AES.MODE_ECB).decrypt(c)
print(flag)

signtime

task

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
from hashlib import sha1
from Crypto.Util.number import bytes_to_long
from ecdsa.ecdsa import Public_key, Private_key, Signature, generator_192
from datetime import datetime
from random import randrange

banner = """                                                
    //   / /     //   ) )     //    ) )     //   ) )     // | | 
   //____       //           //    / /     ((           //__| | 
  / ____       //           //    / /        \\         / ___  | 
 //           //           //    / /           ) )    //    | | 
//____/ /    ((____/ /    //____/ /     ((___ / /    //     | |  

Welcome to this CTF challenge!
you have THREE choices:
- sign_time to get a signature
- verify to verify the signature
- I kown the secret to get the flag
You only have TWO chances per connection. Best wish for you!
"""


generator = generator_192
order = generator.order()
hint_message = ''
flag_content = ''

private_key_value = randrange(1, order - 1)
public_key = Public_key(generator, generator * private_key_value)
private_key = Private_key(public_key, private_key_value)

def sign_current_time():
    current_time = datetime.now()
    current_month = int(current_time.strftime("%m"))  
    current_seconds = int(current_time.strftime("%S"))  
    formatted_time = f"{current_month}:{current_seconds}"
    message = f"The time is {formatted_time}"
    message_hash = sha1(message.encode()).digest()  
    signature = private_key.sign(bytes_to_long(message_hash), randrange(100, 100 + current_seconds))  
    return {"time": message, "r": hex(signature.r), "s": hex(signature.s)}

def verify_signature():
    user_message = input("Enter the message: ")
    user_r = input("Enter r in hexadecimal form: ")
    user_s = input("Enter s in hexadecimal form: ")
    message_hash = sha1(user_message.encode()).digest() 
    signature_r = int(user_r, 16)
    signature_s = int(user_s, 16)
    signature = Signature(signature_r, signature_s)  
    return public_key.verifies(bytes_to_long(message_hash), signature)

def start_challenge():
    print(banner)
    for _ in range(2):
        user_choice = input("Enter your option: ")
        if user_choice == 'sign_time':
            print(sign_current_time())
        elif user_choice == 'verify':
            if verify_signature():
                print(f"The hint is: {hint_message}")
                exit(0)
            else:
                print("Signature verification failed.")
        elif user_choice  == 'I kown the secret':
                if input("Enter the secret: ") == hex(private_key_value):
                    print(f"The flag is: {flag_content}")
                    exit(0)
        else:
            print("Invalid option!")


    
if __name__ == "__main__":
    start_challenge()

ECDSA签名算法,通过时间戳来签名,然后通过验证签名来获取flag signature = private_key.sign(bytes_to_long(message_hash), randrange(100, 100 + current_seconds)) 传入的是hash和k,k很小,直接爆破

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
from hashlib import sha1
from Crypto.Util.number import *
from ecdsa.ecdsa import Public_key, Private_key, Signature, generator_192
from pwn import *

r=remote('',)
r.recvuntil(b"Enter your option: ")
r.sendline(b"sign_time")

a=eval(r.recvline().split().decode())
message=a['time']
r=eval(a['r'])
s=eval(a['s'])

generator = generator_192
order = generator.order()

message_hash=bytes_to_long(sha1(message.encode()).digest())
sign=Signature(r,s)

for k in range(100,160):
    d=(k*s-message_hash)*inverse(r,order)%order
    public_key=Public_key(generator,generator*d)
    private_key=Private_key(public_key,d)
    if private_key.verify(message_hash,sign):
        print(k)
        print(d)
        m=hex(d)
        r.sendline(b"I kown the secret")
        r.sendlineafter(b"Enter the secret: ",m.encode())
        r.interactive()
        break

dance

task

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
from Crypto.Util.number import *
from secret import flag

m = [int(i) for i in bin(bytes_to_long(flag))[2:].zfill(len(flag) * 8)]

p = 0x1A0111EA397FE69A4B1BA7B6434BACD764774B84F38512BF6730D2A0F6B0F6241EABFFFEB153FFFFB9FEFFFFFFFFAAAB
E = EllipticCurve(GF(p), [0, 4])
G1, G2 = E.gens()
o1, o2 = G1.order(), G2.order()
r = [randint(1, o1 - 1) for _ in range(len(m) + 1)]
c = []
for i in range(len(m)):
    A = r[i] * G1 + m[i] * G2
    B = m[i] * G1 + r[i + 1] * G2
    c.extend(A + B)
open("out.txt", "w").write(f"c = {c}")

su也是这种类型的题目,双线性配对,G1和G2已知,flag头前几个bits也知道,

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
from Crypto.Util.number import *

p = 0x1A0111EA397FE69A4B1BA7B6434BACD764774B84F38512BF6730D2A0F6B0F6241EABFFFEB153FFFFB9FEFFFFFFFFAAAB
K=GF(p)
E = EllipticCurve(K, [0, 4])
o=793479390729215512516507951283169066088130679960393952059283337873017453583023682367384822284289
G1, G2 = E.gens()

out=eval(open('out.txt','r').read().split('=')[-1])
cs=[]
for i in range(0,len(out),3):
    c=(out[i],out[i+1],out[i+2])
    cs.append(E(c))

T=G1.weil_pairing(G2,o)

m='0'
for i in range(1,len(cs)):
    now=m[i-1]
    ci=cs[i-1]
    cii=cs[i]
    Ti=G1.weil_pairing(ci,o)
    Tii=G2.weil_pairing(cii,o)
    tmp=Ti*Tii % p
    if tmp==1:
        m+=now
    else:
        m+=str(1-int(now))

flag=long_to_bytes(int(m,2))
print(flag)

right_data

task

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
22
from Crypto.Util.number import *
from secret import flag
from random import shuffle

modulus = 257
key = list(flag)
with open("output.txt", "w") as f:
    for k in range(0, len(key)):
        key1 = getRandomRange(1, modulus)
        key2 = (key[k] + key1) % modulus
        coefs = []
        for _ in range((modulus - 1) ** 2 - 1):
            c1, c2, c3 = (
                getRandomRange(1, modulus),
                getRandomRange(1, modulus),
                getRandomRange(1, modulus),
            )
            coefs.append(c1, c2, (c1 * key1 + c2 * key2 + c3) % modulus)
        shuffle(coefs)
        for i in coefs:
            s = str(i[0]) + " " + str(i[1]) + " " + str(i[2])
            f.write(s + "\n")

key都是小值,可以爆破

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
from Crypto.Util.number import *
from tqdm import *

def findxyy(x,y):
    for i in range(65535):
        if ((x*C1[i]+y*C2[i])%257 == Value[i] ):
            return False
    return True

def findm():
    for x in range(1,257):
        for y in range(1,257):
            if findxyy(x,y):
                m=(y-x)%257
                return chr(m)
            
f=open('output.txt','r')
flag=""

for _ in range(42):
    C1=[]
    C2=[]
    Value=[]
    for i in range(65535):
        tmp=f.readline().split(' ')
        c1=int(tmp[0])
        c2=int(tmp[1])
        value=int(tmp[2])
        C1.append(c1)
        C2.append(c2)
        Value.append(value)
    flag+=findm()

print(flag)