至少给L坐了2次第一的位置(前排留念嘛.... 手快抢了道一血, 还有一道数据拿不到卡了半年... 还有道最后竟然....卡慌了...

# Guess | DONE

麻了... 这道题手快 甚至忘了 hint 就直接开始日,竟然抢到了一血,奈思。运气不辍..

# 究极非预期:

# Enc:

c=gmrnmodn2c = g ^ m r ^ n\mod n ^ 2

# Dec:

λ=(p1)(q1)\lambda = (p-1)(q-1)

μ=(gλmodn2n)1modn\mu = (\frac{g ^ \lambda \mod n ^ 2}{n}) ^ {-1}\mod n

m=(cλmodn2)1nμmodnm = \frac{(c^\lambda\mod n^2)-1}{n}*\mu\mod n

# try:

随便试的... 然后发现解密拿到的都是 3 位数,合理猜测是 key, 打进去 0 或者 1 直接丢。发现多那几次出来的对应 0 或者 1 不变。多连几次,修 dict

plain=dec (n-1)# 即解密 -1

cipher=enc(plain,plain)

c1=gplain×plain×key1rnmodn2c1 = g^{plain\times plain\times key1}r ^ {n}\mod n^2

c2=gplain×plain×key2rnmodn2c2=g ^ {plain\times plain\times key2}r ^ {n}\mod n^2

c1,c2 中的 plain*plain 那块可以当作是 - 1*-1 , 因此,

c1=gkey1rnmodn2,c2=gkey2rnmodn2c1 = g^{key1}r^n\mod n^2,c2=g^{key2}r^n\mod n^2

解密之后,发现就是我们需要的 key, 而题目里面的 key 是本地读取的,所以肯定不会变。就反复打就出来了

key=dec(cipher)

from pwn import *
from Crypto.Util.number import *
from hashlib import sha256
import string
from pwnlib.util.iters import mbruteforce
dict={718:1,244:1,566:0,244:1,558:0,810:1,899:1,585:0,903:0,641:1,237:1,333:1,216:1,184:0,142:0,751:0,637:0,288:0,130:0,121:1,745:1,498:0,542:1,158:1,783:0,281:1,647:1,860:1,746:0,558:0,349:0,751:0,899:0,746:0,286:1,718:0,885:0,526:1,888:1,498:0,638:0,751:0,241:1,216:1,186:1,977:1,148:0,355:0,123:1,299:0,577:0,427:0,113:1,983:0,309:1,614:0,400:1,119:0,550:0,114:0,877:1,918:1,939:0,944:1,128:1,201:1,548:1,396:1,416:0,653:1,995:0,313:0,521:0,646:1,461:1,780:1,129:1,611:0,936:1,942:0,530:0,613:1,307:0,271:0,685:0,430:1,232:1,639:0}
table = string.ascii_letters+string.digits
def pow():
    io.recvuntil("?+")
    suffix = io.recv(12).decode("utf8")
    io.recvuntil("== ")
    cipher = io.recvline().strip().decode("utf8")
    proof = mbruteforce(lambda x: sha256((x + suffix).encode()).hexdigest() ==
                        cipher, table, length=4, method='fixed')
    io.sendline(proof) 
def get_Public_key():
    io.recvuntil('n = ')
    n = int(io.recvline()[:-1])
    io.recvuntil('g = ')
    g = int(io.recvline()[:-1])
    return n,g
def Step_2(Cip):
    io.recv()
    io.sendline(str(Cip))
    io.recvline()
    Plaintext = int(io.recvline()[:-1])
    return Plaintext
def Step_3(m0,m1):
    io.recv()
    io.sendline(str(m0))
    io.recv()
    io.sendline(str(m1))
    io.recvline()
    Ciphertext = int(io.recvline()[:-1])
    return Ciphertext
def Step_4(ciphertext):
    io.recv()
    io.sendline(str(ciphertext))
    io.recvline()
    STR = int(io.recvline()[:-1])
    return STR
if __name__ == "__main__":
    while 1:
        try:
            io = remote("47.104.85.225",57811)
            pow()
            for i in range(32):
                n,g = get_Public_key()
                plaintext = Step_2(n-1)
                ciphertext = Step_3(plaintext,plaintext)
                num = Step_4(ciphertext)
                if num in dict:
                    io.sendline(str(dict[num]))
                    print(num)
                else:
                    io.sendline(str((num+i+1)%2))
                    print(num,str((num+i+1)%2))
            io.interactive()
        except:
            io.close()

# 预期解:

IND-CCA2 安全模型,hint 里面给出了 hint=key * Matrix, Matrix 是 4 * 12 的矩阵,R 数字很大, 并且 hint 里面行向量在 key 里面。格基规约 和前四个 key 一起就能拿到 key 顺序就有了 可以等等官方 wp? (可能会被咕咕咕咕?)

# myRSA | DONE

连接数据拿错了一开始.... 痛失血..... 难过...

等连接等半天,就二分查 p+q, 然后就分解掉 n 了 就好了。然后正常解密 根据 encry 去解密

from pwn import *
from Crypto.Util.number import *
from hashlib import sha256
import string
from pwnlib.util.iters import mbruteforce
table = string.ascii_letters+string.digits
def pow():
    io.recvuntil("?+")
    suffix = io.recv(12).decode("utf8")
    io.recvuntil("== ")
    cipher = io.recvline().strip().decode("utf8")
    proof = mbruteforce(lambda x: sha256((x + suffix).encode()).hexdigest() ==
                        cipher, table, length=4, method='fixed')
    io.sendline(proof) 
def getdate():
    io.recvuntil(b'Welcome to use my better RSA!!!!!!So, what do you want now?')
    io.recvuntil(b'This is my public key:\nn = ')
    n = (io.recv())
    e = 0x10001
    io.sendline('1')
    io.recv()
    io.sendline(b'\x01')
    io.recvuntil(b'Your encry message:\n')
    c = io.recv()
    return n,c
if __name__ == "__main__":
    io = remote("47.104.85.225",49856)
    pow()
    n,c = getdate()
    print(n)
    print(c)
    io.sendline('2')
    io.interactive()
[+] MBruteforcing: Found key: "i2H2"
<ipython-input-2-368d9c4bc365>:15: BytesWarning: Text is not bytes; assuming ASCII, no guarantees. See https://docs.pwntools.com/#bytes
  io.sendline(proof)
<ipython-input-2-368d9c4bc365>:22: BytesWarning: Text is not bytes; assuming ASCII, no guarantees. See https://docs.pwntools.com/#bytes
  io.sendline('1')
b'68195486242491905197433526004507369032272491135696932334326068024040058438599110281712712885705379034982984472056474100930481463577289211609825797634637699853031185421002896320599047956784229329089847286676426757567349199706750131259258373177336457657022868600117460778180849110456709646379002371134272563633\ne = 65537\n1. encry \n2. getflag\n3. exit\n'
b'4597266005632522801147627000660857649183366325885623347197089667591563216981756164256482446594948053316793620258055892298724248421726012140081053576547521297239629024402710879218821331887650345980788144066048868262298302137125886809420799790304816147986191762960289700205264554882006937334365726206855596559080070895663726388199502053612930185897787061099796111936877366936203717889564522795854776615268505308467045914833319009227673259174528506512902671304308976\n1. encry \n2. getflag\n3. exit\n'
<ipython-input-2-368d9c4bc365>:35: BytesWarning: Text is not bytes; assuming ASCII, no guarantees. See https://docs.pwntools.com/#bytes
  io.sendline('2')
[*] Switching to interactive mode
This is your favourite:
40868648891657711786598328718113063065545453011282156865784206192978574818052122882184358068236975753192772828954658973145613760735845195818217664683661925592185852021605700613828161411554664790911594417203233292649407034179935773181418886730406997379175819237199860137490038826629366907380520875211156420009016730301710339622873008218484776846907819947820161852183069547449851535930768116416974211148236437262996588115644260055582849718976117916680029401709166538197581624667147067231655542792069808991633694902877465348527151882218715188113964032172846627464279982722447664427600294582370983132847084133297955553459809699744364828552913355798427543451791875776222341962020592533940215035327061046030408462348449028012044372949233825736289928601740622679907051748552640
1. encry 
2. getflag
3. exit

第一串数字 n 就是下面脚本里面的 n 中间比较长的就是 com 最后一个数据就是 最后的 c

from Crypto.Util.number import *
p,q,r = getPrime(512),getPrime(512),getPrime(int(512*2.0314159265358979))
n = p*q
com = p**2 * (p + 3*q - 1 ) + q**2 * (q + 3*p - 1)  + 2*p*q + p + q + r*2
com = 4597266005632522801147627000660857649183366325885623347197089667591563216981756164256482446594948053316793620258055892298724248421726012140081053576547521297239629024402710879218821331887650345980788144066048868262298302137125886809420799790304816147986191762960289700205264554882006937334365726206855596559080070895663726388199502053612930185897787061099796111936877366936203717889564522795854776615268505308467045914833319009227673259174528506512902671304308976
left = 1
right = 2**514*2
t = (left + right)//2
for i in range(20000):
    if t**3 - t**2 +t + 4*n <com:
        left = t
    else:
        right = t
    t = (left + right)//2
#print(t)
import gmpy2
n = 68195486242491905197433526004507369032272491135696932334326068024040058438599110281712712885705379034982984472056474100930481463577289211609825797634637699853031185421002896320599047956784229329089847286676426757567349199706750131259258373177336457657022868600117460778180849110456709646379002371134272563633
for i in range(-80000,80000):
    if gmpy2.iroot((t-i)**2-4*n,2)[1]:
        print(t-i)
        print(gmpy2.iroot((t-i)**2-4*n,2)[0])
        tmp = t-i
        tmp2 = gmpy2.iroot((t-i)**2-4*n,2)[0]
        p = (tmp+tmp2)//2
        q = tmp - p
print(p*q==n)
phi = (p-1)*(q-1)
e = 0x10001
d = inverse(e,phi)
c = 40868648891657711786598328718113063065545453011282156865784206192978574818052122882184358068236975753192772828954658973145613760735845195818217664683661925592185852021605700613828161411554664790911594417203233292649407034179935773181418886730406997379175819237199860137490038826629366907380520875211156420009016730301710339622873008218484776846907819947820161852183069547449851535930768116416974211148236437262996588115644260055582849718976117916680029401709166538197581624667147067231655542792069808991633694902877465348527151882218715188113964032172846627464279982722447664427600294582370983132847084133297955553459809699744364828552913355798427543451791875776222341962020592533940215035327061046030408462348449028012044372949233825736289928601740622679907051748552640
c = c//(p**2 * (p + 3*q - 1 ) + q**2 * (q + 3*p - 1)  + 2*p*q + p + q)
print(long_to_bytes(pow(c,d,n)))

# Random_RSA | DONE

py2 实现 random 白给题

# shared secret | Lnengmao-Team

拉跨的我... 题目都没认真看一开始... 睡了一下午 五点才开始起来做。

h2(m)

sha256(m)sha256(m)

key_gen(nbits):

s=getrandbits(nbits)modp,pk=gsmodps = getrandbits(nbits) \mod p,pk = g^s\mod p\\

enc(m,pk):

E=gemodp,V=gvmodps=v+e(h2(EV))E = g^e\mod p,V=g^v\mod p\\ s = v+e(h2(E||V))

c=mpke+vmodpc = m*pk^{e+v}\mod p

我们发现

E=ge×skI×dd,V=gv×skI×ddE_- = g^{e\times skI\times dd} , V_-=g^{v\times skI\times dd}

E=ge,V=gvE = g^{e},V=g^{v}

c=m×(EV)skImodp=m×(EV)inv(dd,p1)modpc = m\times (EV)^{skI}\mod p =m\times (E_-V_-)^{inv(dd,p-1)}\mod p

这样子我们拥有 E_ 和 V_ 那么我们只需要拿到这个 dd 就能够解密得到 m , 拿到 dd 就是要去 在 encoder 里面进行消元 然后实现最后拿到的是 r
第一组 encoder 是由已知的 prefix 生成的,我们发现我们可以拿到这个最开始的 encoder, 根据普通的 dh 就行了,接着去消元。
rk_gen 只要消元 拿到 r (直接这么消元就行了 emmm.) 但是听说还有种 韦达定理, 用已知的 x 当根 然后一条多项式 直接带进去 就是算出来是 0 加上这个 r 就是 r
那就直接直接通完四关

接着根据

mul=sk4×dd1×dd2×dd3×dd4modpmul = sk^4\times dd_1\times dd_2\times dd_3\times dd_4\mod p

其中四个 dd 都是已知的,那么接着就拿到了 sk 的四次,发现 p%4 =3, 那么我们首先先对 sk 进行一个费玛的定理拿到的是 sk 的 2 次 % p 于是,我们就可以 计算

sk=(sk2)(p+1)//4modpsk = (sk^2)^{(p+1)//4}\mod p

就拿到了这个 sk
而对于最后一段就是对 enc 进行一个解密
EV 都是已知,c 也已知 直接计算就出了。。。

确实能猫了。。。丢个本地和远程的脚本

from Crypto.Util.number import*
from pwn import *
from hashlib import sha256
from libnum import n2s, s2n
p, g = 0xb5655f7c97e8007baaf31716c305cf5950a935d239891c81e671c39b7b5b2544b0198a39fd13fa83830f93afb558321680713d4f6e6d7201d27256567b8f70c3, \
       0x85fd9ae42b57e515b7849b232fcd9575c18131235104d451eeceb991436b646d374086ca751846fdfec1ff7d4e1b9d6812355093a8227742a30361401ccc5577
def h2(m):
    return int(sha256(m).hexdigest(), 16)
def get_pk_sk():
    io.recv()
    io.sendline(b"1")
    io.recvuntil(b"Please take good care of it!\n")
    pk,sk = eval(io.recvline()[:-1].replace(b'L',b' '))
    return pk,sk
def get_cha2_data():
    io.recvuntil(b'(')
    c,(E_,V_,s_) = eval(b'('+io.recvline()[:-1].replace(b'L',b' '))
    io.recvuntil(b'prefix, encoder = ')
    encoder , prefix = eval(io.recvline()[:-1].replace(b'L',b' '))
    return c,E_,V_,s_,encoder,prefix
def get_r(encoder,x1):
    r = 1
    xishu = 1
    for i in range(len(encoder)):
        xishu = xishu*(-1)
        tmp = encoder[i]*xishu % p
        r = (tmp - x1 * r)%p
    if len(encoder)%2 == 0:
        return r
    else:
        return p-r
def local():
    pk,sk = get_pk_sk()
    DD = []
    io.recv()
    io.sendline(b'2')
    io.recvuntil(b'The cipher shared to you\n')
    c,E_,V_,s_,encoder,prefix = get_cha2_data()
    x1 = pow(int(prefix,16),sk,p)%p
    r = get_r(encoder,x1)
    ddd = h2(n2s(int(prefix,16)).rjust(64, b'\x00') + n2s(r).rjust(64, b'\x00'))  | 1
    inv_ddd = inverse(ddd,p-1)
    EVsk = pow(E_ * V_ ,inv_ddd,p)%p
    DD.append(ddd)
    m = (c* pow(EVsk,-1,p))%p  
    ans = hex(m)[2:]
    io.sendline(ans.encode())
    c,E_,V_,s_,encoder,prefix = get_cha2_data()
    x1 = pow(int(prefix,16),sk,p)%p
    r = get_r(encoder,x1)
    ddd = h2(n2s(int(prefix,16)).rjust(64, b'\x00') + n2s(r).rjust(64, b'\x00'))  | 1
    inv_ddd = inverse(ddd,p-1)
    EVsk = pow(E_ * V_ ,inv_ddd,p)%p
    DD.append(ddd)
    m = (c* pow(EVsk,-1,p))%p  
    ans = hex(m)[2:]
    io.sendline(ans.encode())
    c,E_,V_,s_,encoder,prefix = get_cha2_data()
    x1 = pow(int(prefix,16),sk,p)%p
    r = get_r(encoder,x1)
    ddd = h2(n2s(int(prefix,16)).rjust(64, b'\x00') + n2s(r).rjust(64, b'\x00'))  | 1
    inv_ddd = inverse(ddd,p-1)
    EVsk = pow(E_ * V_ ,inv_ddd,p)%p
    DD.append(ddd)
    m = (c* pow(EVsk,-1,p))%p  
    ans = hex(m)[2:]
    io.sendline(ans.encode())
    c,E_,V_,s_,encoder,prefix = get_cha2_data()
    x1 = pow(int(prefix,16),sk,p)%p
    r = get_r(encoder,x1)
    ddd = h2(n2s(int(prefix,16)).rjust(64, b'\x00') + n2s(r).rjust(64, b'\x00'))  | 1
    inv_ddd = inverse(ddd,p-1)
    EVsk = pow(E_ * V_ ,inv_ddd,p)%p
    DD.append(ddd)
    m = (c* pow(EVsk,-1,p))%p  
    ans = hex(m)[2:]
    io.sendline(ans.encode())
    ddddd = 1
    for i in DD:
        ddddd =  ddddd * i % p 
    d= inverse(4,p-1)
    io.recvuntil(b'some other information!\n')
    mul = int(io.recvline()[:-1],16)
    sk1 = pow(mul*inverse(ddddd,p),d,p)
    sk1 = pow(sk1,(p+1)//4,p)
    io.sendline(b'3')
    io.recvuntil(b"choice>")
    ss = io.recvline()[:-1].replace(b'L',b'')
    c,(E,V,s) = eval(ss)
    flag = n2s(c*pow(E*V,-sk1,p) % p )
    print(flag)
    io.close()
    return flag
def yuancheng():
    pk,sk = get_pk_sk()
    DD = []
    io.recv()
    io.sendline(b'2')
    io.recvuntil(b'The cipher shared to you\n')
    c,E_,V_,s_,encoder,prefix = get_cha2_data()
    x1 = pow(int(prefix,16),sk,p)%p
    r = get_r(encoder,x1)
    ddd = h2(n2s(int(prefix,16)).rjust(64, b'\x00') + n2s(r).rjust(64, b'\x00'))  | 1
    inv_ddd = inverse(ddd,p-1)
    EVsk = pow(E_ * V_ ,inv_ddd,p)%p
    DD.append(ddd)
    m = (c* pow(EVsk,-1,p))%p  
    ans = hex(m)[2:]
    io.sendline(ans.encode())
    c,E_,V_,s_,encoder,prefix = get_cha2_data()
    x1 = pow(int(prefix,16),sk,p)%p
    r = get_r(encoder,x1)
    ddd = h2(n2s(int(prefix,16)).rjust(64, b'\x00') + n2s(r).rjust(64, b'\x00'))  | 1
    inv_ddd = inverse(ddd,p-1)
    EVsk = pow(E_ * V_ ,inv_ddd,p)%p
    DD.append(ddd)
    m = (c* pow(EVsk,-1,p))%p  
    ans = hex(m)[2:]
    io.sendline(ans.encode())
    c,E_,V_,s_,encoder,prefix = get_cha2_data()
    x1 = pow(int(prefix,16),sk,p)%p
    r = get_r(encoder,x1)
    ddd = h2(n2s(int(prefix,16)).rjust(64, b'\x00') + n2s(r).rjust(64, b'\x00'))  | 1
    inv_ddd = inverse(ddd,p-1)
    EVsk = pow(E_ * V_ ,inv_ddd,p)%p
    DD.append(ddd)
    m = (c* pow(EVsk,-1,p))%p  
    ans = hex(m)[2:]
    io.sendline(ans.encode())
    c,E_,V_,s_,encoder,prefix = get_cha2_data()
    x1 = pow(int(prefix,16),sk,p)%p
    r = get_r(encoder,x1)
    ddd = h2(n2s(int(prefix,16)).rjust(64, b'\x00') + n2s(r).rjust(64, b'\x00'))  | 1
    inv_ddd = inverse(ddd,p-1)
    EVsk = pow(E_ * V_ ,inv_ddd,p)%p
    DD.append(ddd)
    m = (c* pow(EVsk,-1,p))%p  
    ans = hex(m)[2:]
    io.sendline(ans.encode())
    ddddd = 1
    for i in DD:
        ddddd =  ddddd * i % p 
    d= inverse(4,p-1)
    io.recvuntil(b'some other information!\n')
    mul = int(io.recvline()[:-2],16)
    sk1 = pow(mul*inverse(ddddd,p),d,p)
    #print(p%4)
    sk1 = pow(sk1,(p+1)//4,p)
    io.sendline(b'3')
    io.recvuntil(b"choice>")
    ss = io.recvline()[:-1].replace(b'L',b'')
    c,(E,V,s) = eval(ss)
    flag = n2s(c*pow(E*V,-sk1,p) % p )
    print(flag)
    io.close()
    return flag
if __name__ == "__main__":
    while 1:
        try:
            io = remote("192.168.3.88",12198)
            flag = local()
            if b'flag'  in flag:
                break
        except:
            io.close()
            continue
    while 1:
        try:
            io = remote("47.104.85.225",62351)
            flag = yuancheng()
            if b'flag'  in flag:
                break
        except:
            io.close()
            continue

<!--2021 年 08 月 23 日 /-->

请我喝[茶]~( ̄▽ ̄)~*

De3B4to 微信支付

微信支付

De3B4to 支付宝

支付宝