RSA-256
RSA签到太简单了
N = 77483692467084448965814418730866278616923517800664484047176015901835675610073
e = 65537
c = 43711206624343807006656378470987868686365943634542525258065694164173101323321
p,q=1025252665848145091840062845209085931,75575216771551332467177108987001026743883
long_to_bytes(pow(c,invert(e,(p-1)*(q-1)),N))
#utflag{just_send_plaintext}
Beginner: Anti-dcode.fr
这题一开始还真虎了一下,给了caeser加密的flag并加了大量字符,只需要把26种情况列出来,然后用正则表达式找出来就行了
import re
import string
def caeser(m,i):
t = ''
for v in m:
if v in string.ascii_lowercase:
t += chr(ord('a')+(ord(v)-ord('a')+i)%26)
else:
t += v
return t
msg = open('c3_LoooongCaesarCipher.txt').read()
for i in range(26):
tmsg = caeser(msg,i)
it = re.finditer(r"utflag\{[a-zA-Z_]+\}",tmsg)
for v in it:
print(v.group())
#utflag{rip_dcode}
numbers go brrr
现在怎么弄个题就有远端,先是生成一个随机种子,然后生成key进行AES加密,远端提供加密和flag密文,但是由于seed太小只有10**6爆破一下即可。不过这个远端确实没大意思,手工得到密文再爆破即可。
#!/usr/bin/env python3
from Crypto.Cipher import AES
from Crypto.Util.Padding import pad
from Crypto.Random import random
seed = random.randint(0, 10 ** 6)
def get_random_number():
global seed
seed = int(str(seed * seed).zfill(12)[3:9])
return seed
def encrypt(message):
key = b''
for i in range(8):
key += (get_random_number() % (2 ** 16)).to_bytes(2, 'big')
cipher = AES.new(key, AES.MODE_ECB)
ciphertext = cipher.encrypt(pad(message, AES.block_size))
return ciphertext.hex()
print("Thanks for using our encryption service! To get the encrypted flag, type 1. To encrypt a message, type 2.")
while True:
print("What would you like to do (1 - get encrypted flag, 2 - encrypt a message)?")
user_input = int(input())
if(user_input == 1):
break
print("What is your message?")
message = input()
print("Here is your encrypted message:", encrypt(message.encode()))
flag = open('/src/flag.txt', 'r').read();
print("Here is the encrypted flag:", encrypt(flag.encode()))
c = 'bafc0c65ea2e10ae53ae0c36cb2d7f622f8fedbc2aee2ccf18c8f63ec55026538ec4ffcd12d6d1e828ff19481e78a360'
c = bytes.fromhex(c)
from Crypto.Cipher import AES
def get_random_number():
global seed
seed = int(str(seed * seed).zfill(12)[3:9])
return seed
def encrypt(message):
key = b''
for i in range(8):
key += (get_random_number() % (2 ** 16)).to_bytes(2, 'big')
cipher = AES.new(key, AES.MODE_ECB)
ciphertext = cipher.decrypt(message)
return ciphertext
for seed in range(10**6):
flag = encrypt(c)
if b'utflag{' in flag:
print(flag)
#utflag{deep_seated_and_recurring_self-doubts}
numbers go brrr 2
与上题基本相似,但需要猜对3次,这个可以作到100次,这样如果爆破就会超时。所以这题先生成字典,其它直接查表回复即可。
#!/usr/bin/env python3
from Crypto.Cipher import AES
from Crypto.Util.Padding import pad
from Crypto.Random import random
seed = random.randint(0, 10 ** 6)
def get_random_number():
global seed
seed = int(str(seed * seed).zfill(12)[3:9])
return seed
def encrypt(message):
key = b''
for i in range(8):
key += (get_random_number() % (2 ** 16)).to_bytes(2, 'big')
cipher = AES.new(key, AES.MODE_ECB)
ciphertext = cipher.encrypt(pad(message, AES.block_size))
return key.hex(), ciphertext.hex()
print("Thanks for using our encryption service! To get the start guessing, type 1. To encrypt a message, type 2.")
print("You will need to guess the key (you get 250 guesses for one key). You will do this 3 times!")
for i in range(3):
seed = random.randint(0, 10 ** 6)
print("Find the key " + str(i + 1) + " of 3!")
key = encrypt(b"random text to initalize key")[0]
while True:
print("What would you like to do (1 - guess the key, 2 - encrypt a message)?")
user_input = int(input())
if(user_input == 1):
break
print("What is your message?")
message = input()
key, ciphertext = encrypt(message.encode())
print("Here is your encrypted message:", ciphertext)
print("You have 250 guesses to find the key!")
found = False
for j in range(250):
print("What is your guess (in hex)?")
guess = str(input()).lower()
if guess == key:
print("You found the key!")
found = True
break
else:
print("That is not the key!")
if not found:
print("You did not find the key!")
exit(0)
flag = open('/src/flag.txt', 'r').read();
print("Here is the flag:", flag)
from pwn import *
from Crypto.Cipher import AES
from Crypto.Util.Padding import pad
from Crypto.Random import random
def get_random_number():
global seed
seed = int(str(seed * seed).zfill(12)[3:9])
return seed
def encrypt(message):
key = b''
for i in range(8):
key += (get_random_number() % (2 ** 16)).to_bytes(2, 'big')
cipher = AES.new(key, AES.MODE_ECB)
ciphertext = cipher.encrypt(pad(message, AES.block_size))
return key.hex(), ciphertext.hex()
# 字典 cipher:key
dic = {}
msg = b"random text to initalize key"
for seed in range(10**6):
key,cipher = encrypt(msg)
dic[cipher] = key
#attack
p = remote('betta.utctf.live', 2435)
context(arch='amd64', log_level='debug')
for _ in range(3):
p.sendlineafter(b"What would you like to do (1 - guess the key, 2 - encrypt a message)?\n", b'2')
p.sendlineafter(b"What is your message?", msg)
p.recvuntil(b"Here is your encrypted message:")
c = p.recvline().decode().strip()
key = dic[c]
p.sendlineafter(b"What would you like to do (1 - guess the key, 2 - encrypt a message)?\n", b'1')
p.sendlineafter(b"What is your guess (in hex)?\n", key.encode())
p.recvline()
p.recvline()
p.interactive()
bits and pieces
回到RSA,给了3组n,e,c第1个n可以在factor.db分解,第2和第3有公因子
n1=16895844090302140592659203092326754397916615877156418083775983326567262857434286784352755691231372524046947817027609871339779052340298851455825343914565349651333283551138205456284824077873043013595313773956794816682958706482754685120090750397747015038669047713101397337825418638859770626618854997324831793483659910322937454178396049671348919161991562332828398316094938835561259917841140366936226953293604869404280861112141284704018480497443189808649594222983536682286615023646284397886256209485789545675225329069539408667982428192470430204799653602931007107335558965120815430420898506688511671241705574335613090682013
e1= 65537
c1=7818321254750334008379589501292325137682074322887683915464861106561934924365660251934320703022566522347141167914364318838415147127470950035180892461318743733126352087505518644388733527228841614726465965063829798897019439281915857574681062185664885100301873341937972872093168047018772766147350521571412432577721606426701002748739547026207569446359265024200993747841661884692928926039185964274224841237045619928248330951699007619244530879692563852129885323775823816451787955743942968401187507702618237082254283484203161006940664144806744142758756632646039371103714891470816121641325719797534020540250766889785919814382
n2= 22160567763948492895090996477047180485455524932702696697570991168736807463988465318899280678030104758714228331712868417831523511943197686617200545714707332594532611440360591874484774459472586464202240208125663048882939144024375040954148333792401257005790372881106262295967972148685076689432551379850079201234407868804450612865472429316169948404048708078383285810578598637431494164050174843806035033795105585543061957794162099125273596995686952118842090801867908842775373362066408634559153339824637727686109642585264413233583449179272399592842009933883647300090091041520319428330663770540635256486617825262149407200317
e2= 65537
c2= 19690520754051173647211685164072637555800784045910293368304706863370317909953687036313142136905145035923461684882237012444470624603324950525342723531350867347220681870482876998144413576696234307889695564386378507641438147676387327512816972488162619290220067572175960616418052216207456516160477378246666363877325851823689429475469383672825775159901117234555363911938490115559955086071530659273866145507400856136591391884526718884267990093630051614232280554396776513566245029154917966361698708629039129727327128483243363394841238956869151344974086425362274696045998136718784402364220587942046822063205137520791363319144
n3= 30411521910612406343993844830038303042143033746292579505901870953143975096282414718336718528037226099433670922614061664943892535514165683437199134278311973454116349060301041910849566746140890727885805721657086881479617492719586633881232556353366139554061188176830768575643015098049227964483233358203790768451798571704097416317067159175992894745746804122229684121275771877235870287805477152050742436672871552080666302532175003523693101768152753770024596485981429603734379784791055870925138803002395176578318147445903935688821423158926063921552282638439035914577171715576836189246536239295484699682522744627111615899081
e3= 65537
c3= 17407076170882273876432597038388758264230617761068651657734759714156681119134231664293550430901872572856333330745780794113236587515588367725879684954488698153571665447141528395185542787913364717776209909588729447283115651585815847333568874548696816813748100515388820080812467785181990042664564706242879424162602753729028187519433639583471983065246575409341038859576101783940398158000236250734758549527625716150775997198493235465480875148169558815498752869321570202908633179473348243670372581519248414555681834596365572626822309814663046580083035403339576751500705695598043247593357230327746709126221695232509039271637
from Crypto.Util.number import *
#第1段factor.db可分解
p = 129984014749130366259742130443330376923069118727641845190136006048911945242427603092160936004682857611235008521722596025476170673607376869837675885556290582081941522328978811710862857253777650447221864279732376499043513950683086803379743964370215090077032772967632331576620201195241241611325672953583711295127
q = n1//p
m1 = pow(c1,invert(e1,(p-1)*(q-1)),n1)
long_to_bytes(m1)
#2,3有公因子
p = gcd(n2,n3)
q = n2//p
m2 = pow(c2,invert(e2,(p-1)*(q-1)),n2)
long_to_bytes(m2)
q = n3//p
m3 = pow(c3,invert(e3,(p-1)*(q-1)),n3)
long_to_bytes(m3)
#utflag{oh_no_it_didnt_work_</3_i_guess_i_can_just_use_standard_libraries_in_the_future}
Cryptordle
这题有点意思,随机生成5个字节串a-z,然后可以猜6次,如果不正确会返回对应位置差的积模31。
假设串里没有yz,然后猜zzzzz这个差的积表示为a*b*c*d*e=k1 (mod 31),然后第2次猜zzzzy那么第2次结果就是a*b*c*d*(e-1)=k2 两式可以得到a*b*c*d=k1-k2,第3次a*b*c*(d-1)*e=k3得到a*b*c*e=k1-k3这样猜5次可能得到5个算式,从而求出与猜测数的差。在原串不包含的yz的情况(概率很大)即可猜对,得到flag
#!/usr/bin/env python3
import random
wordlist = open('/src/wordlist.txt', 'r').read().split('\n')
for word in wordlist:
assert len(word) == 5
for letter in word:
assert letter in 'abcdefghijklmnopqrstuvwxyz'
for attempt in range(3):
answer = random.choice(wordlist)
num_guesses = 0
while True:
num_guesses += 1
print("What's your guess?")
guess = input().lower()
assert len(guess) == 5
for letter in guess:
assert letter in 'abcdefghijklmnopqrstuvwxyz'
if guess == answer:
break
response = 1
for x in range(5):
a = ord(guess[x]) - ord('a')
b = ord(answer[x]) - ord('a')
response = (response * (a-b)) % 31
print(response)
if num_guesses > 6:
print("Sorry, you took more than 6 tries. No flag for you :(")
exit()
else:
print("Good job! Onward...")
if num_guesses <= 6:
print('Nice! You got it :) Have a flag:')
flag = open('/src/flag.txt', 'r').read()
print(flag)
else:
print("Sorry, you took more than 6 tries. No flag for you :(")
from pwn import *
def getv(k):
for a in range(1,26):
for b in range(1,26):
for c in range(1,26):
for d in range(1,26):
for e in range(1,26):
if a*b*c*d*e%31 == k[0] and a*b*c*d%31 == (k[0]-k[1])%31 and a*b*c*e%31 == (k[0]-k[2])%31 and a*b*d*e%31 == (k[0]-k[3])%31 and a*c*d*e%31 == (k[0]-k[4])%31:
print(a,b,c,d,e)
return [a,b,c,d,e]
ss = 'zzzzz zzzzy zzzyz zzyzz zyzzz'.split()
p = remote('betta.utctf.live', 7496)
context(arch='amd64', log_level='debug')
for _ in range(3):
k = [0]*5
for i in range(5):
p.sendlineafter(b"What's your guess?\n", ss[i].encode())
k[i] = int(p.recvline())
r = getv(k)
ans = bytes([97+(25-i) for i in r])
p.sendlineafter(b"What's your guess?\n", ans)
p.recvline()
p.recvline()
p.interactive()
#utflag{sometimes_pure_guessing_is_the_strat}
simple signature
这题始终没弄明白是怎么回事,没有附件,名字应该是说rsa签名,连接远端后输入数字会返回签名,相同的值连续输入后签名会不同。一直没弄明白要干嘛,但是连上以后发现如果先输入2,下交再输入1,就会得到与2一样的签名,也就达到预测的目的。
*Forgery
这题提示是rev,crypto,C++写的吧,没看懂,跟pwn似的。