只打了19号的题,运气很好,dance二血✌️,复现一下前两天的
RSA1
题目:
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
'''
已知:
变换为
一元copper解多项式,得到e
再通过
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())
我们可以知道是固定值,计算如下:
的形式是
'flag{xxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxx}'+'bin(getprime(86))'
每一位都加三,并且m_1的长度等于130(42+len('0b')+86))
可以知道转为数字后
但是有个坑,就是在小端序第89位的'}'
(ord('}')+3)%128后变成了0,所以是
exp:
k=0
for i in range(130):
if i != 130 - 42:
k += 3 * pow(2,i*8)
else:
k -= 125 *pow(2,i*8)
print(k)
#138604255630984394504644405862999441108691457990544710059664868220625513430462483763119797291779992529360824019886958759717736876661453044335745573603330761817432828924688993026332102549607397901351619425324993583087500714061523945925857368498922102768458574857510324727265052999967460998294909713988129273348867
最后只需将
使用明文线性相关攻击,求出来后由于m>n,所以爆破一下即可
exp:
from Crypto.Util.number import *
from libnum import *
import sys
sys.setrecursionlimit(500000) # 将默认1000层递归深度提升至500000
n = 176871561120476589165761750300633332586877708342448994506175624203633860119621512318321172927876389631918300184221082317741380365447197777026256405312212716630617721606918066048995683899616059388173629437673018386590043053146712870572300799479269947118251011967950970286626852935438101046112260915112568392601
c1 = 47280375006817082521114885578132104427687384457963920263778661542552259860890075321953563867658233347930121507835612417278438979006705016537596357679038471176957659834155694284364682759675841808209812316094965393550509913984888849945421092463842546631228640293794745005338773574343676100121000764021207044019
c2 = 176231410933979134585886078013933649498379873444851943224935010972452769899603364686158279269197891190643725008151812150428808550310587709008683339436590112802756767140102136304346001599401670291938369014436170693864034099138767167055456635760196888578642643971920733784690410395944410255241615897032471127315
c3 = 135594807884016971356816423169128168727346102408490289623885211179619571354105102393658249292333179346497415129785184654008299725617668655640857318063992703265407162085178885733134590524577996093366819328960462500124201402816244104477018279673183368074374836717994805448310223434099196774685324616523478136309
PR.<x> = PolynomialRing(Zmod(n))
f = (c3 - x) ^ 5 - c2 ^ 7
f = f.monic()
root = f.small_roots(2 ** 128, beta=0.4, epsilon=0.015)
if root:
e = int(root[0])
print(e)
e = 281211879955223558268422413173406510291
k = 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)
PR.<x> = PolynomialRing(Zmod(n))
f = c1 - (e * x) ^ 2835
g = c2 - (x + k) ^ 2025
res = GCD(f, g)
m = int(-res.monic().coefficients()[0])
print(f'm={m}')
m = 169566881296280536230561129157151622566504043926679156667071395769823565229041445364663653128728776719686646238643163970346144733740570892537769104873476638766502858266706871058713811974921647126159418457230812714218445199879590506393283382966594445673462477218575655861719659885889626296053470513451622819648
for i in range(2 ^ 20):
mm = m + i * n
flag = long_to_bytes(mm)
if b'flag' in flag:
print(flag)
#flag{2404dcef-4223-417d-aee0-c236241f2320}
EzRSA
题目:
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
'''
刚开始以为这道题会跟SUCTF的SU_rsa一样,后来发现有一些小改动,在这里说明一下
都有下式:
可以写成
但是在SU_rsa中,e只有256bit,在这个式子中e相比于n很小,那么对式子影响很小,最后除掉n后k基本不变,可以写成
而在这道题中
e是1023bit,和n是差不多大的,那这个时候就很大,除掉n之后只能知道k的高位,可以写成
测试数据发现k>>512 = (>>512) + 1
后面算出s%e的值,由于e是1023bit所以s就是p+q,再解方程即可
exp:
from Crypto.Util.number import *
import hashlib
from tqdm import trange
from multiprocessing import Pool
N = 136118062754183389745310564810647775266982676548047737735816992637554134173584848603639466464742356367710495866667096829923708012429655117288119142397966759435369796296519879851106832954992705045187415658986211525671137762731976849094686834222367125196467449367851805003704233320272315754132109804930069754909
e = 84535510470616870286532166161640751551050308780129888352717168230068335698416787047431513418926383858925725335047735841034775106751946839596675772454042961048327194226031173378872580065568452305222770543163564100989527239870852223343451888139802496983605150231009547594049003160603704776585654802288319835839
c = 33745401996968966125635182001303085430914839302716417610841429593849273978442350942630172006035442091942958947937532529202276212995044284510510725187795271653040111323072540459883317296470560328421002809817807686065821857470217309420073434521024668676234556811305412689715656908592843647993803972375716032906
d_m = 4640688526301435859021440727129799022671839221457908177477494774081091121794107526784960489513468813917071906410636566370999080603260865728323300663211132743906763686754869052054190200779414682351769446970834390388398743976589588812203933
leak = 12097621642342138576471965047192766550499613568690540866008318074007729495429051811080620384167050353010748708981244471992693663360941733033307618896919023
dh = d_m <<234
k_high = (e*dh) // N
kh = k_high >> 999
k_high = (k_high>>512)+1
k_high = k_high << 512
# print(k_high)
hash512 = bytes_to_long(hashlib.sha512(long_to_bytes(kh)).digest())
def attack(range):
low = range[0]
up = range[1]
for dl in trange(low, up):
hash224 = bytes_to_long(hashlib.sha224(long_to_bytes(dl)).digest())
k_low = leak ^^ hash224 ^^ hash512
k = k_high + k_low
k_inv = inverse(k, e)
s = (N + 1 + k_inv) % e
if 511 <= int(s).bit_length() <= 515:
# print(f"dl = {dl}")
var('p,q')
f1 = p+q == s
f2 = p*q == N
res = solve([f1, f2], [p, q])
print(res)
break
ranges = [(i, i + 524288) for i in range(0, 2 ^ 24, 524288)]
with Pool(32) as pool:
r = list(pool.imap(attack, ranges))
running
题目:
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
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?'
了解了一下丰数,其实就是这个数的除它自己以外的因子相加大于它自己,那么就是丰数
举例:12的除其以外的因子有1,2,3,4,6 他们相加等于,所以12是丰数
丰数n的丰度就是分解后其中的所有正因数之和除以n
举例:12的所有正因数1,2,3,4,6,12相加等于28,那么12的丰度为
这道题就是求丰度为6的数,其中具体原因还没弄清楚
求解方法在论文
exp:
from Crypto.Util.number import *
from Crypto.Cipher import AES
from Crypto.Util.Padding import pad
from hashlib import md5
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?'
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)
#flag{1fa54a4b-1a2d-4e7f-9a8f-550293728b9b}
factor
题目:
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))
# n = 5605777780127871552103278440489930168557569118966981388111283042550796167470265465148458919374665519335013101681890408413810351780671950283765145543168779446153786190869731166707967097095246677053262868926963631796027692694223765625053269102325714361312299011876036815423751522482629914361369303649193526946050137701205931577449326939722902280884984494828850611521784382097900268639648421100760612558110614208245291400961758972415881709281708443424129033685255718996719201537066717587527029554871540574867831957154286334639399985379381455084604901293000229526196544921067214723085504463673412082637877637982771445298815007769526806112008703908400170846707986989384244531990469279604588770393462375930699135443458952703826608237292999895910024613311408883134789788541751697007502656798556053417265191533053158952284994030769145926816478390761642058013769635850833893158830591398862163134753203291719549474871116653745337968227
# c = 2998195560453407057321637509862236387961676411996988529185696118404592349869917006166370346762261303282478779647282039317061146533808487789458703169149689179547543732935053220010550004328207373171271534689897340156346458951776319267981966893926724550629182100766890856964207263709029611781806548130358294543573874132473259788387939849997550651614987993962540192023207354839106090274252125961835070701748643163379053118598595995782448140944376681636633592442158453965800439960134688017496184195454406927204485213436540382637720118180670197194949275760000729877093621741313147190401896114633643891311672542703928421032698499968701052818985292683628072129271790220674145955527935027879112279336148316425115255710066132502392447843608711463775710558880259205308541126041959858947252063815158749021817255637836170676726466347847422352280599210078359786387419424076245960344657767332883964636288493649066530215094453490169688507988
已知:
直接开三次方得到p的高位,然后爆破+copper得到p
from Crypto.Util.number import *
from tqdm import trange
import gmpy2
n = 5605777780127871552103278440489930168557569118966981388111283042550796167470265465148458919374665519335013101681890408413810351780671950283765145543168779446153786190869731166707967097095246677053262868926963631796027692694223765625053269102325714361312299011876036815423751522482629914361369303649193526946050137701205931577449326939722902280884984494828850611521784382097900268639648421100760612558110614208245291400961758972415881709281708443424129033685255718996719201537066717587527029554871540574867831957154286334639399985379381455084604901293000229526196544921067214723085504463673412082637877637982771445298815007769526806112008703908400170846707986989384244531990469279604588770393462375930699135443458952703826608237292999895910024613311408883134789788541751697007502656798556053417265191533053158952284994030769145926816478390761642058013769635850833893158830591398862163134753203291719549474871116653745337968227
c = 2998195560453407057321637509862236387961676411996988529185696118404592349869917006166370346762261303282478779647282039317061146533808487789458703169149689179547543732935053220010550004328207373171271534689897340156346458951776319267981966893926724550629182100766890856964207263709029611781806548130358294543573874132473259788387939849997550651614987993962540192023207354839106090274252125961835070701748643163379053118598595995782448140944376681636633592442158453965800439960134688017496184195454406927204485213436540382637720118180670197194949275760000729877093621741313147190401896114633643891311672542703928421032698499968701052818985292683628072129271790220674145955527935027879112279336148316425115255710066132502392447843608711463775710558880259205308541126041959858947252063815158749021817255637836170676726466347847422352280599210078359786387419424076245960344657767332883964636288493649066530215094453490169688507988
t = int(gmpy2.iroot(n,3)[0])
ph = t >> 348 << 348
def attack(bound):
low = bound[0]
up = bound[1]
for i in trange(low,up):
kbits = 335
phigh = ph + i*2^335
R.<x> = PolynomialRing(Zmod(n))
f = phigh + x
res = f.monic().small_roots(X=2^kbits,beta=0.33,epsilon=0.02)
if res != []:
print(res)
for root in res:
p = int(phigh + root)
if n % p == 0:
print(f"p = {p}")
ranges = [(i,i + 256) for i in range(0,2^13,256)]
from multiprocessing import Pool
with Pool(32) as pool:
r = list(pool.imap(attack,ranges))
# p = 177641852143539875144076287104359901067433280125353192376052994247805596999311993133680118926203330508832035411734411354655205181670634659281906946269134849688257950688607255823034295123844247237760781276134032579722586580714406466623980282093209193430049447821706112292714446557721627445986171788731664465623
a和b对于n来说是小数,使用二元copper
from Crypto.Util.number import *
import itertools
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)
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)
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
c = 2998195560453407057321637509862236387961676411996988529185696118404592349869917006166370346762261303282478779647282039317061146533808487789458703169149689179547543732935053220010550004328207373171271534689897340156346458951776319267981966893926724550629182100766890856964207263709029611781806548130358294543573874132473259788387939849997550651614987993962540192023207354839106090274252125961835070701748643163379053118598595995782448140944376681636633592442158453965800439960134688017496184195454406927204485213436540382637720118180670197194949275760000729877093621741313147190401896114633643891311672542703928421032698499968701052818985292683628072129271790220674145955527935027879112279336148316425115255710066132502392447843608711463775710558880259205308541126041959858947252063815158749021817255637836170676726466347847422352280599210078359786387419424076245960344657767332883964636288493649066530215094453490169688507988
p =177641852143539875144076287104359901067433280125353192376052994247805596999311993133680118926203330508832035411734411354655205181670634659281906946269134849688257950688607255823034295123844247237760781276134032579722586580714406466623980282093209193430049447821706112292714446557721627445986171788731664465623
N = n // p
R.<x,y> = PolynomialRing(Zmod(N))
f = p^2 + 2*p*x + x^2 + p*y + x*y
res = small_roots(f,(2^346,2^346),m=2,d=3)
for root in res:
q = p + int(root[0])
r = p + int(root[0] + root[1])
if n % q == 0:
print(f"q = {q}")
r = n // p // q
phi = (p-1)*(q-1)*(r-1)
d = inverse(65537,phi)
m = pow(c,d,n)
print(long_to_bytes(int(m)))
# flag{24e33eda-f57c-42da-92c5-e0b39414cded}
right_data
题目:
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")
这题全靠猜了,没什么意思,判断能不能直接等于数据
如果能直接等于那就是错的
exp:
from tqdm import *
modulus = 257
def find(i, j):
for t in range((modulus - 1) ** 2 - 1):
if (i * coefs1[t] + j * coefs2[t]) % modulus == values[t]:
return False
return True
def findflag():
for i in range(1, modulus):
for j in range(1, modulus):
if find(i, j):
return chr((j - i) % modulus)
flag = ""
with open("output.txt", "r") as f:
for _ in trange(0, 42):
coefs1 = []
coefs2 = []
values = []
for i in range((modulus - 1) ** 2 - 1):
s = f.readline().replace("\n", "").split(" ")
coefs1.append(int(s[0]))
coefs2.append(int(s[1]))
values.append(int(s[2]))
flag += findflag()
print(flag)
funny_rsa
题目:
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))
先通过funny2和funny3求出来n
再通过funny1爆破出来phi,就出来了
from gmpy2 import *
from Crypto.Util.number import *
c = 13541898381047120826573743874105965191304100799517820464813250201030319771155430755606644860103469823030581858410957600027665504533335597988508084284252510961847999525811558651340906333101248760970154440885012717108131962658921396549020943832983712611749095468180648011521808106480590665594160479324931351996812185581193608244652792936715504284312172734662364676167010674359243219959129435127950232321130725013160026977752389409620674167037650367196748592335698164875097139931376389630867192761783936757260359606379088577977154378217235326249540098268616890307702288393952949444753648206049856544634755301197410481479
h = -17696257697673533517695215344482784803953262308315416688683426036407670627060768442028628137969719289734388098357659521255966031131390425549974547376165392147394271974280020234101031837837842620775164967619688351222631803585213762205793801828461058523503457022704948803795360591719481537859524689187847958423587638744086265395438163720708785636319741908901866136858161996560525252461619641697255819255661269266471689541673348377717503957328827459396677344554172542244540931545166846117626585580964318010181586516365891413041095399344533013057011854734701706641516027767197631044458866554524544179750101814734153116374
h = abs(h)
k1=23686728880494758233026798487859622755203105120130180108222733038275788082047755828771429849079142070779731875136837978862880500205129022165600511611807590195341629179443057553694284913974985006590617143873019530710952420242412437467917519539591683898715990297750494900923245055632544763410401540518654522017115269508183482044872091052235608170710105631742176900306097734799793264202179181242015892763311753674799273300604804820015447161950996038795518844564861004398396796284113803759208011
k2 = 419166458284161364374927086939132546372091965414091344286510440034452974193054721041229068769658972346759176374539266235862042787888391905466876330331208651698002159575012622762558316612596034044109738533275009086940744966244759977014078484433213617582101347769476703012517531619023366639507114909172774156647998737369356116119513795863130218094614475699956104117183821832339358478426978211282822163928764161915824622224165694904342224081321345691796882691318330781141960650263488927837990954860719950761728580780956673732592771855694502630374907978111094148614378212006604233062606116168868545120407836000858982789824582335703891535021579560434875457656655941164757860852341484554015214879991896412137447010444797452119431147303295803678311972500421396900616845556636124424993090559354406417222700637726789045926994792374756038517484548544506630672251868349748176389591615802039026216656891403871728516658502023897343287181822303758976641229952646993446276281728919020747050486979968215989594984778920359425264076558022228448529089047021814759587052098774273578311709416672952218680244714492318709603579024
n = (k2+1025)//k1
for i in range(-2000,2000):
print(i)
h0 = h + i
d = invert(65537,h0)
m = pow(c,d,n)
if k1% m == 0:
flag = k1 // m
print(long_to_bytes(flag))
break
print(long_to_bytes(5044833682931814367881036090727702841234957943094051805420875375031047763007750978962055801191968383860156687597666360268370292861))
# true:flag{aB3-CdE7_FgH9-iJkLmNoPqRsT-UvWxYz1234567890}
signtime
题目:
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()
漏洞点在:
signature = private_key.sign(bytes_to_long(message_hash), randrange(100, 100 + current_seconds))
k = 100+当前时间的秒数
那其实可以选择爆破60个数,得到k
或者我想的是直接在xx:xx:01的时候来开靶机,那么k=randrange(100, 101)
这样的话直接把k=100带进去就可以了
exp:
from hashlib import sha1
from Crypto.Util.number import *
from ecdsa.ecdsa import Public_key, Private_key, Signature, generator_192
from random import randrange
msg = 'The time is 1:1'
nonce = 100
R = 0xbce1ebbcf6b5e0d4f2c190fd9c33f078230a21f0cef7b151
S = 0xee1e9f12a84055f3d455ef318c36f0b1bf10c7761e731fc6
msg = sha1(msg.encode()).digest()
msg = bytes_to_long(msg)
n = 6277101735386680763835789423176059013767194773182842284081
import gmpy2
secret = (S * nonce - msg) * gmpy2.invert(R, n) % n
print(hex(secret))
#0x871bc70c4490294fd460a267cb1af04ed56ce09de06a90ae
dance
题目:
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}")
配对的题,要是基本概念不知道的师傅可以看下我SUCTF的那篇博客
通过题目可以知道,如果m这一bit是0,那么
如果m这一bit是1,那么
那我举一个例子
如果第一位是0,后一位也是0
计算
我们可以发现如果相邻两位都是0的话,,相邻两位都是1的情况同理
如果第一位是0,后一位是1
这种情况是满足不了式子的,第一位是0,第二位是1同理
最终我们可以知道
是否满足 | 的bit位 | |
---|---|---|
0 | 是 | 0 |
0 | 否 | 1 |
1 | 是 | 1 |
1 | 否 | 0 |
exp:
from Crypto.Util.number import *
import ast
p = 0x1A0111EA397FE69A4B1BA7B6434BACD764774B84F38512BF6730D2A0F6B0F6241EABFFFEB153FFFFB9FEFFFFFFFFAAAB
K = GF(p)
E = EllipticCurve(K, (0, 4))
with open("output.txt") as f:
cs = [E(*xy) for xy in ast.literal_eval(f.read())]
G1, G2 = E.gens()
o1, o2 = G1.order(), G2.order()
flag = "0"
for i in range(0,len(cs)-1):
print(i)
w1 = cs[i].weil_pairing(G1, o1)
w2 = cs[i+1].weil_pairing(G2, o1)
w21 = w2 ^-1
if (k == 0) :
if (w1 == w21):
flag += '0'
else:
k = 1
flag += '1'
elif(k == 1):
if (w1 == w21):
flag += '1'
else:
k = 0
flag += '0'
print(long_to_bytes(int(flag,2)))
# b'flag{0331d347-6fd2-4159-9c84-0f78373933bd}'