hgame2021 密码学 writeup
·520 words·3 mins
Table of Contents
HGAME 2021网络攻防大赛crypto wp #
EncryptedChats #
Description
Switch 的病友 Million 来监狱探监…
Challenge Address
Switch: 你好老伙汁
Million: 你好
Switch: 所以为什么这家伙在这里
Liki: 因为我是来记录你们谈话内容的
Million: 好吧
Million: 不过我可以提一个要求吗
Liki: ?
Million: 我们...换一个群聊
Switch: 好啊! 我看看, 就换到加法群聊吧!
Switch: 喂, 帮忙选一个质数 g 吧
Liki: ??, 12602983924735419868428783329859102652072837431735895060811258460532600319539509800915989811879506790207025505003183121812480524033163157114086741486989697
Million: 这位女士,可以劳烦您再为我们选择一个质数 p 吗
Liki: ???...那就, 30567260905179651419358486099834315837354102714690253338851161207042846254351374572818884286661092938876675032728700590336029243619773064402923830209873155153338320502164587381848849791304214084993139233581072431814555885408821184652544361671134564827265516331283076223247829980225591857643487356406284913560960657053777612115591241983729716542192518684003840806442329098770424504275465756739925434019460351138273272559738332984560095465809481270198689251655392941966835733947437503158486731906649716026200661065054914445245468517406404904444261196826370252359102324767986314473183183059212009545789665906197844518119 吧, 够大了吗?
Million: 好的, 我选好我的 a 了, 那么 A = 6407001517522031755461029087358686699246016691953286745456203144289666065160284103094131027888246726980488732095429549592118968601737506427099198442788626223019135982124788211819831979642738635150279126917220901861977041911299607913392143290015904211117118451848822390856596017775995010697100627886929406512483565105588306151304249791558742229557096175320767054998573953728418896571838697779621641522372719890056962681223595931519174265357487072296679757688238385898442549594049002467756836225770565740860731932911280385359763772064721179733418453824127593878917184915316616399071722555609838785743384947882543058635
# A = g ^ a % p = pow(g, a, p)
Switch: okay, b 也选好了, B = 5522084830673448802472379641008428434072040852768290130448235845195771339187395942646105104638930576247008845820145438300060808178610210847444428530002142556272450436372497461222761977462182452947513887074829637667167313239798703720635138224358712513217604569884276513251617003838008296082768599917178457307640326380587295666291524388123169244965414927588882003753247085026455845320527874258783530744522455308596065597902210653744845305271468086224187208396213207085588031362747352905905343508092625379341493584570041786625506585600322965052668481899375651376670219908567608009443985857358126335247278232020255467723
# B = g ^ b % p = pow(g, b, p)
Liki: ????
Million: {'iv': 'd3811beb5cd2a4e1e778207ab541082b', 'encrypted_flag': '059e9c216bcc14e5d6901bcf651bee361d9fe42f225bc0539935671926e6c092'}
Switch: {'iv': 'b4259ed79d050dabc7eab0c77590a6d0', 'encrypted_flag': 'af3fe410a6927cc227051f587a76132d668187e0de5ebf0608598a870a4bbc89'}
Million: 再见伙汁
Switch: 再见
Liki: ?????
加法群的幂是乘法
from Crypto.Cipher import AES
from Crypto.Util.Padding import pad, unpad
from Crypto.Util.number import long_to_bytes
import hashlib
import gmpy2 as gp
from binascii import a2b_hex
A = 6407001517522031755461029087358686699246016691953286745456203144289666065160284103094131027888246726980488732095429549592118968601737506427099198442788626223019135982124788211819831979642738635150279126917220901861977041911299607913392143290015904211117118451848822390856596017775995010697100627886929406512483565105588306151304249791558742229557096175320767054998573953728418896571838697779621641522372719890056962681223595931519174265357487072296679757688238385898442549594049002467756836225770565740860731932911280385359763772064721179733418453824127593878917184915316616399071722555609838785743384947882543058635
B = 5522084830673448802472379641008428434072040852768290130448235845195771339187395942646105104638930576247008845820145438300060808178610210847444428530002142556272450436372497461222761977462182452947513887074829637667167313239798703720635138224358712513217604569884276513251617003838008296082768599917178457307640326380587295666291524388123169244965414927588882003753247085026455845320527874258783530744522455308596065597902210653744845305271468086224187208396213207085588031362747352905905343508092625379341493584570041786625506585600322965052668481899375651376670219908567608009443985857358126335247278232020255467723
p = 30567260905179651419358486099834315837354102714690253338851161207042846254351374572818884286661092938876675032728700590336029243619773064402923830209873155153338320502164587381848849791304214084993139233581072431814555885408821184652544361671134564827265516331283076223247829980225591857643487356406284913560960657053777612115591241983729716542192518684003840806442329098770424504275465756739925434019460351138273272559738332984560095465809481270198689251655392941966835733947437503158486731906649716026200661065054914445245468517406404904444261196826370252359102324767986314473183183059212009545789665906197844518119
g = 12602983924735419868428783329859102652072837431735895060811258460532600319539509800915989811879506790207025505003183121812480524033163157114086741486989697
x1 = gp.invert(g,p)*A%p
x2 = gp.invert(g,p)*B%p
key1 = x1*x2*g%p
shared_secret = key1
sha1 = hashlib.sha1()
sha1.update(str(shared_secret).encode('ascii'))
key = sha1.digest()[:16]
iv1 = a2b_hex('d3811beb5cd2a4e1e778207ab541082b')
iv2= a2b_hex('b4259ed79d050dabc7eab0c77590a6d0')
data1 = a2b_hex('059e9c216bcc14e5d6901bcf651bee361d9fe42f225bc0539935671926e6c092')
data2 = a2b_hex('af3fe410a6927cc227051f587a76132d668187e0de5ebf0608598a870a4bbc89')
decrypt1 = AES.new(key,AES.MODE_CBC,iv1)
decrypt2 = AES.new(key,AES.MODE_CBC,iv2)
flag1 = decrypt1.decrypt(data1)
flag2 = decrypt2.decrypt(data2)
print(flag1,flag2)
# hgame{AdD!tiVe-Gr0up~DH_K3y+eXch@nge^4nd=A3S}
夺宝大冒险2 #
lfsr基础
from icecream import *
from pwn import *
# nc 30607
sh = remote('182.92.108.71', 30607)
ans = []
for i in range(10):
buf = sh.recvuntil('guess:')
sh.sendline('-1')
sh.recvuntil('Wrong, the secret is ')
buf = int(sh.recvuntil('\n')[:-1])
# print(buf)
ans.append(buf)
print(ans)
bstr = ''
for i in ans:
ic(i, bin(i)[2:].rjust(4, '0'))
bstr += bin(i)[2:].rjust(4, '0')
s = bstr
ic(bstr,len(s))
init = int(bstr[:40],2)
ic(init)
class LXFIQNN():
def __init__(self, init, mask, length):
self.init = init
self.mask = mask
self.lengthmask = 2**(length+1)-1
def next(self):
nextdata = (self.init << 1) & self.lengthmask
i = self.init & self.mask & self.lengthmask
output = 0
while i != 0:
output ^= (i & 1)
i = i >> 1
nextdata ^= output
self.init = nextdata
return output
def random(self, nbit):
output = 0
for _ in range(nbit):
output <<= 1
output |= self.next()
return output
prng = LXFIQNN(init, 0b1011001010001010000100001000111011110101, 40)
for i in range(81):
secret = prng.random(4)
sh.sendline(str(secret))
print(sh.recvuntil('guess'))
sh.interactive()
#hgame{lfsr_121a111y^use-in&crypto}
夺宝大冒险1 #
保证$a<c,b<c,a,b,c互质$,task1,2 很容易求出来
task3用选择明文是思想先把a,b消掉,对tmp1,tmp2取最大公因数,平均跑50次由一组适合我们这个算法的a,b,c
from icecream import *
from libnum import *
from pwn import *
# print(sh.recvline())
def t1(sh):
s = sh.recvline().decode()
ic(s)
s =s.split(',')
print(((s[0][1:]), (s[1][:-1])))
a,c = (int(s[0][1:]),int(s[1][:-2]))
m1 = int(sh.recvline())
m2 = int(sh.recvline())
b = (m2-a*m1)%c
# ic(b,int(sh.recvline()))
# ic(b)
sh.sendline(str(b))
def t2(sh):
c = int(sh.recvline())
m = [0]+[int(sh.recvline()) for i in range(3)]
a = (m[2]-m[3])*(invmod(m[1]-m[2],c))
a %= c
b = m[2]-a*m[1]
b %= c
# ic(a, sh.recvline())
# ic(b, sh.recvline())
# ic(a,b)
sh.sendline(str(a))
sh.sendline(str(b))
def t3(sh):
m = [123]+[int(sh.recvline()) for i in range(7)]
ic(m, len(m))
# tmp1 = -(m[7]-m[6])*(m[5]-m[4])-(m[6]-m[5])*(m[6]-m[5])
tmp1 = abs((m[4]-m[3])*(m[2]-m[1])-(m[3]-m[2])*(m[3]-m[2]))
tmp2 = abs((m[7]-m[6])*(m[5]-m[4])-(m[6]-m[5])*(m[6]-m[5]))
ic(tmp1, tmp2)
tmp = gcd(tmp1, tmp2)
# ic(tmp, int(sh.recvline()))
# ic(tmp)
sh.sendline(str(tmp))
# print(tmp1 % .cgen, tmp2 % gen.c)
# nc 182.92.108.71 30641
def main():
tot =0
while 1:
tot+=1
try:
sh = remote('182.92.108.71', 30641)
t1(sh)
t2(sh)
t3(sh)
buf = (sh.recvall())
print(buf)
if b'win' in buf:
print(f'try {tot} times')
break
except:
pass
if __name__ == '__main__':
main()
'''
[+] Receiving all data: Done (56B)
[*] Closed connection to 182.92.108.71 port 30641
b'win\nhgame{Cracking^prng_Linear)Congruential&Generators}\n'
try 46 times
'''