ctfshow 卷王杯

两题没出😢,mt19937有点可惜了,被填充给坑了。。。

现在把题目都复现一下

概率RSA

没给附件,在交互的时候给出了一个信息

str((((pow(temp_c, key.d, key.n))&5) * random.randint(1,10000))%(2*(random.randint(1,10000)))) = 1048

刚开始看感觉挺奇怪的,后面想了一下那个&5似乎可以看作&1,而且还没限制交互次数,就考虑利用奇偶性的oracle去做,注意到这里会附加一个随机数打乱性质,于是我们同一个数据多跑几次即可

from pwn import *
from sage.all import *
from tqdm import tqdm
p=remote('pwn.challenge.ctf.show',28182)
e=65537
p.recvuntil('N = ')
n=int(p.recvline()[:-1])
p.recvuntil('c = ')
c=int(p.recvline()[:-1])
bound=[0,0,0]
for i in tqdm(range(650,1020)):
 re=[]
 for j in range(10):
  temp=c*pow(2,i*e,n)
  p.recvuntil('temp_c = ')
  p.sendline(str(temp))
  p.recvuntil(' = ')
  re.append(int(p.recvline()[:-1])%2)
 mul=0
 for j in range(10):
  if re[j]==1:
   mul=1
 bound[0]=2*bound[0]+mul*n
 bound[1]=bound[0]+n
 bound[2]=i
print(bound[0]//pow(2,i))
print(bound[1]//pow(2,i))

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

def woohoo():
    a = random.getrandbits(32)
    b = random.getrandbits(32)
    c = random.getrandbits(32)
    d = random.getrandbits(32)
    return (a<<96)+(b<<64)+(c<<32)+(d)

BANNER = """
+-------------+
|    *   *    |
|    *   *    |
| *********** |
|    *   *    |
|             |
|  *********  |
|      *      |
|     *       |
| *********** |
|    *  *     |
|    *  *     |
|   *   *   * |
| **    ***** |
+-------------+

赛事预告: 
比赛名称:ctfshow 卷王杯 
题目难度:无 
出题奖励:usb小台灯+周边钥匙扣 
比赛奖励:单项第1送定制妹子贴纸,单项AK取前3 
比赛时间:2022年2月25日(周五) 18时整 
比赛时长:48小时 
比赛地址:https://ctf.show/challenges 
投稿邮箱:ctfshow@163.com
"""

MENU = """
+-----------------+
|[E]ncrypt        |
|[T]est encryption|
|[8]86            |
+-----------------+
"""

if __name__ == '__main__':
    print(BANNER)
    # 我只泄露一点线索
    # 是谁为爱走钢索
    for i in range(130):
        print(MENU)
        option = input("> ").lower()
        if option == "e":
            print("Enter your message.")
            msg = input("> ").encode()
            msg = pad(msg, AES.block_size)
            key = woohoo()
            iv = woohoo()
            key = long_to_bytes(key).rjust(AES.block_size, b"\x00")
            iv = long_to_bytes(iv).rjust(AES.block_size, b"\x00")
            
            c = AES.new(key, AES.MODE_CBC, iv=iv)
            ct = c.encrypt(msg)
            
            iv = b"never gonna give you up"
            
            print(f"Ciphertext (hex): {ct.hex()}")
            print(f"Key (hex): {key.hex()}")
            print(f"IV (hex): {iv.hex()}")
        elif option == "t":
            flag = open("flag.txt", "rb").read()
            msg = pad(flag, AES.block_size)
            key = woohoo()
            iv = woohoo()

            key = long_to_bytes(key)
            iv = long_to_bytes(iv)
            
            c = AES.new(key, AES.MODE_CBC, iv=iv)
            ct = c.encrypt(msg)
            
            key = b"never gonna let you down"
            
            print(f"Ciphertext (hex): {ct.hex()}")
            print(f"Key (hex): {key.hex()}")
            print(f"IV (hex): {iv.hex()}")
        elif option == "8":
            print("Sa yo na la!")
            break
        else:
            print("What r u DOIN?")
    else:
        print("Never gonna run around and desert you")

一开始被填充坑了,赶时间也没仔细监数据,后面复现的时候试了几个填充就出来,属实离谱

大概思路就是收集624个连续随机数然后预测后面的key

注意到前面自己输信息的key是给了的,iv被字符串掩了,利用ECB模式恢复即可

from pwn import *
from Crypto.Cipher import AES
from Crypto.Util.number import *
from randcrack import RandCrack
p=remote('pwn.challenge.ctf.show',28105)
def woohoo():
    a = rc.predict_getrandbits(32)
    b = rc.predict_getrandbits(32)
    c = rc.predict_getrandbits(32)
    d = rc.predict_getrandbits(32)
    return (a<<96)+(b<<64)+(c<<32)+(d)

def split1(m):
 temp=bin(m)[2:].rjust(128,'0')
 for i in range(4):
  rc.submit(int(temp[32*i:32*(i+1)],2))

rc=RandCrack()
pay='hashhashhashhas'
pay1=bytes_to_long(b'hashhashhashhas\x01')
for i in range(78):
 p.sendline('e')
 p.recvuntil('> ')
 p.sendline(pay)
 p.recvuntil('Ciphertext (hex): ')
 c=int(p.recvline()[:-1],16)
 p.recvuntil('Key (hex): ')
 key=int(p.recvline()[:-1],16)
 key1 = long_to_bytes(key).rjust(AES.block_size, b"\x00")
 aes=AES.new(key1,AES.MODE_ECB)
 iv=bytes_to_long(aes.decrypt(long_to_bytes(c)))^pay1
 split1(key)
 split1(iv)


p.sendline('t')
p.recvuntil('Ciphertext (hex): ')
c=int(p.recvline()[:-1],16)
p.recvuntil('IV (hex): ')
ivv=int(p.recvline()[:-1],16)
print(bin(ivv))
key = woohoo()
iv = woohoo()
print(bin(iv))
key = long_to_bytes(key)
iv = long_to_bytes(iv)
c=long_to_bytes(c)
aes=AES.new(key,AES.MODE_CBC,iv)
print(aes.decrypt(c))

铱锡锡

from Crypto.Util.number import *
import random

class Point:
    global p, a, b
    def __init__(self, x, y):
        self.x = x % p
        self.y = y % p
    
    def __str__(self):
        return f'({self.x}, {self.y})'

    def __add__(self, B):
        x1, y1, x2, y2 = self.x, self.y, B.x, B.y

        if (x1 == 0 and y1 == 0):
            return B
        if (x2 == 0 and y2 == 0):
            return self
        if (x1 == x2 and (y1 + y2) % p == 0):
            return Point(0, 0)
        
        if (x1 != x2 or y1 != y2):
            lam = (y2 - y1) * inverse(x2-x1, p) % p
        else:
            lam = (3*x1**2+a) * inverse(2*y1, p) % p
        
        x = (lam**2 - x1 - x2) % p
        y = (lam * (x1 - x) - y1) % p
        return Point(x, y)
    
    def __rmul__(self, k):
        B = Point(0, 0)
        k = f'{k:b}'
        
        for k_i in k:
            B = B + B
            if (k_i == '1'):
                B = B + self
            
        return B
    
    def __eq__(self, B):
        return self.x == B.x and self.y == B.y

p = 115792089210356248762697446949407573530086143415290314195533631308867097853951
order = 115792089210356248762697446949407573529996955224135760342422259061068512044369
a = -3
b = 41058363725152142129326129780047268409114441015993725554835256314039467401291

WELCOME = """
Welcome to my YeeSheShe!

As I have mentioned before, to predict the value of k, the possibility is also about O(yeesheshe)!

If you know how to capture the probability of O(yeesheshe), you can capture the flag!
"""

MENU = """
Choices:
[1] Test my YeeSheShe
[2] Submit the value of k 
"""

def main():
    print(WELCOME)
    k = random.randint(1,order)
    
    for i in range(7): # Clearlove7
        print(MENU)
        choice = input('> ')
        if (choice == '1'):
            print("As we all have known, Q = kP")
            print("Give me the coordinate of P, and I'll give you the coordinate of Q.")
            x, y = map(int, input("Enter the coordinate of point P: ")[1:-1].split(', '))
            P = Point(x, y)
            Q = k * P
            print(f"The coordinate of Q is {Q}")
        elif (choice == '2'):
            print("Now please tell me the value of k.")
            k_input = input('> ')
            if (k == int(k_input)):
                print("FUIYOH! You have captured the probability of O(yixixi) successfully!")
                with open('flag.txt') as f:
                    flag = f.read()
                print(f"Here is your flag: {flag}")
            else:
                print('HAIYAA! You just fucked up!')
                print('GO AWAY!')
            break
    else:
        print("You cannot finish it in the field of clearlove 7777777")
        print("FAILURE!")

if __name__ == '__main__':
    main()

非常好的一道题目了,虽然不会做😢

这里利用了ECC加密时的一个漏洞,未检测输入的点是否在曲线上,攻击方式被称为invalid point attack

这个或许是我现在接触到的最贴近实际的一个密码学漏洞了,攻击方式也称为Bluetooth attack,是存在于蓝牙协议的一个漏洞

攻击的方式非常巧妙,利用不检测输入的点是否合理,可以任意篡改曲线的b值,从而可以达到在一个光滑曲线群上加密的效果,而我们可以利用pohlig-hellman算法解出私钥,同时通过多次操作解较小的阶,最后利用crt组合求得一个与原阶数的bits一致的值即为所求的私钥

from pwn import *
from sage.all import *
oi=remote('pwn.challenge.ctf.show',28000)
B=[1,5,9,12,38,13]
G=((111400716329737223151348215591382049163897085784802947255747133622415879105394, 39992761736411400081935771079229874378216016675324636692947348968013201165276),
(13719045388076151520803368351989304615465812259733704032402319532249511403233, 70112205679957371132763956439647700048310284796833596573793277095178113815519),
(43073418371286323595156732037737293646818329128791009438524376324397773820726, 35593429086189375972008488132929667910986330958314594350096901828426497889077),
(66433977671962939100073201807983167264694941590643124947273042440494792218015, 21652151330053975273880197568657021519050157521775125899551963970572483258486),
(40092374358375676891557996696416077109395130857602600253780368444671153878383, 1220793250473451325744127538413666357546316742399446078249755026290349789846),
(37673718832712137809127078277795630388877581750162566803210280135148912394288, 56746642413640372892023989284505332312846604225559347665409782919856416362427))
QQ=[]
for i in range(6):
 oi.sendline('1')
 oi.sendline(str(G[i]))
 oi.recvuntil('The coordinate of Q is ')
 x=int(oi.recvuntil(', ')[1:-2])
 y=int(oi.recvuntil('\n')[:-2])
 QQ.append((x,y))
tt=[1,1,2,2,2,1]
aa=[]
bb=[]
for i in range(6):
    print(i)
    p = 115792089210356248762697446949407573530086143415290314195533631308867097853951
    a = -3
    b=B[i]
    E=EllipticCurve(GF(p),[a,b])
    Q=E(QQ[i])
    GG=E(G[i])
    factors, exponents = zip(*factor(E.order()))
    primes = [factors[i] ** exponents[i] for i in range(len(factors))][:-tt[i]]
    K=[]
    mul=1
    for i in primes:
        mul*=i
    for i in primes:
        t=E.order()//i
        k=discrete_log(t*Q,t*GG,operation='+')
        K.append(k)
    aa.append(crt(K,primes))
    bb.append(mul)
print(aa)
print(bb)
pay=crt(aa,bb)
print(pay)
oi.sendline('2')
oi.sendline(str(pay))
oi.interactive()

密码签到

Y3NldHRfZl9jc2FyaF95b3Nwd2l0JTdCbW9qcCF1bCU3RA==

base64后url再遍历栅栏即可

真·简单·不卷·现代密码签到

from Crypto.Util.number import bytes_to_long
from secrets import p,q,r,s,t,flag

n = p * q * r * s * t
e = 2
m = bytes_to_long(os.urandom(500) + flag)
c = pow(m,e,n)

print(p,q,r,s,t,sep='\n')
print(c)

'''
145332367700944303747548912160113939198078051436029477960348968315913956664143693347226702600438608693933768134575289286283267810723137895903153829001826223446477799895493265422562348917012216790077395795861238257357035152687833639085415763850743538206986781418939737511715957738982536382066693822159860701263
116660458253067608044065523310547233337730583902133756095473339390057738510707447906971188577217274861047379404014140178165569604404468897712846876108444468370709141219302291601408652742006268186059762087155933131837323952675627966299810891805398890428420575425160696531236660480933905879208166090591482794763
157931722402853245421436270609912823260313730941283152856444641969403238646482562190531038393124087232554754746464603598717356255570166081501573727336977292059427220330169044611674973569766966838498453232642731737958791706086957762244686953294662693939604300864961637325536379321027705854708492453330690705531
100973451687449518854742673778783266158999451072058606348222018797891147675959983616210003484476577612134482311993701677242007759556951494382833070563369964294544839433671087037596159753825249018950693369209927951667775267086896180395776150188902057785214767230658487267587289809918132337927575673868568976679
93960345071948255233882121683650797512129333868351496468898834736770441398743300745703393838320587998953678254272245400344928586394089488734271897540051673996675973642347859306921527430850673334243441180183460927865980713929789963587608547554858491264614271309608925634272282292964002897650355047792764365447
9144597920381774885442906257311149465702295057238600973973598305004391534618770363098565074541384771979931799878381439264848137810353858418200992191234142740194489573540381681161219332611454834544291634628456257670178843484698324641739324687497388018406214041657278323855749902661752448796122517061920880552011343608609622885787617238758769398972009949575526258430282648817039091284796330585349957724522615105102735930258969562103112238020133587096826386028128471852377225525357348919204333121695432662339443004327748973224423132988376298843862056631045488285859621661802413201793962883794915513510467912312842687601478117040419013468059983777273699192408773551806581458197324620065210523913467414181480875280203580147077789063808832356486197271376615883221558265591069223727607585313240243619515521180600435114131162272519949101464089935441251751426683447701142156416866113627126765919641034042927519834229168536331952275698122511502745177547569813354280565828372968703810158857859460406828090199683324760956105682902577189283246483314689365570862217407333103243336691401424548702387876409228977278498691200028282744239512091373110111792177228979867318546462714521296256938374618636206565791541769138267080789842400796973226733816939794717596194090232425688504890234304977612220790858557639246367437740975495450011676714198668471438814299689325208882261918460708833888406187912527346628912894921059735420931656953236560178909180587372589456926690219114173193202048332172538564489660440225377822914097420807957784201785024166011709377791129
'''

类似于rabin,直接有限域开方

p=145332367700944303747548912160113939198078051436029477960348968315913956664143693347226702600438608693933768134575289286283267810723137895903153829001826223446477799895493265422562348917012216790077395795861238257357035152687833639085415763850743538206986781418939737511715957738982536382066693822159860701263
q=116660458253067608044065523310547233337730583902133756095473339390057738510707447906971188577217274861047379404014140178165569604404468897712846876108444468370709141219302291601408652742006268186059762087155933131837323952675627966299810891805398890428420575425160696531236660480933905879208166090591482794763
r=157931722402853245421436270609912823260313730941283152856444641969403238646482562190531038393124087232554754746464603598717356255570166081501573727336977292059427220330169044611674973569766966838498453232642731737958791706086957762244686953294662693939604300864961637325536379321027705854708492453330690705531
s=100973451687449518854742673778783266158999451072058606348222018797891147675959983616210003484476577612134482311993701677242007759556951494382833070563369964294544839433671087037596159753825249018950693369209927951667775267086896180395776150188902057785214767230658487267587289809918132337927575673868568976679
t=93960345071948255233882121683650797512129333868351496468898834736770441398743300745703393838320587998953678254272245400344928586394089488734271897540051673996675973642347859306921527430850673334243441180183460927865980713929789963587608547554858491264614271309608925634272282292964002897650355047792764365447
c=9144597920381774885442906257311149465702295057238600973973598305004391534618770363098565074541384771979931799878381439264848137810353858418200992191234142740194489573540381681161219332611454834544291634628456257670178843484698324641739324687497388018406214041657278323855749902661752448796122517061920880552011343608609622885787617238758769398972009949575526258430282648817039091284796330585349957724522615105102735930258969562103112238020133587096826386028128471852377225525357348919204333121695432662339443004327748973224423132988376298843862056631045488285859621661802413201793962883794915513510467912312842687601478117040419013468059983777273699192408773551806581458197324620065210523913467414181480875280203580147077789063808832356486197271376615883221558265591069223727607585313240243619515521180600435114131162272519949101464089935441251751426683447701142156416866113627126765919641034042927519834229168536331952275698122511502745177547569813354280565828372968703810158857859460406828090199683324760956105682902577189283246483314689365570862217407333103243336691401424548702387876409228977278498691200028282744239512091373110111792177228979867318546462714521296256938374618636206565791541769138267080789842400796973226733816939794717596194090232425688504890234304977612220790858557639246367437740975495450011676714198668471438814299689325208882261918460708833888406187912527346628912894921059735420931656953236560178909180587372589456926690219114173193202048332172538564489660440225377822914097420807957784201785024166011709377791129
PR.<x>=PolynomialRing(Zmod(p))
f=x^2-c
aes1=f.roots()
PR.<x>=PolynomialRing(Zmod(q))
f=x^2-c
aes2=f.roots()
PR.<x>=PolynomialRing(Zmod(r))
f=x^2-c
aes3=f.roots()
PR.<x>=PolynomialRing(Zmod(s))
f=x^2-c
aes4=f.roots()
PR.<x>=PolynomialRing(Zmod(t))
f=x^2-c
aes5=f.roots()
for i1 in aes1:
    for i2 in aes2:
        for i3 in aes3:
            for i4 in aes4:
                for i5 in aes5:
                    m=int(crt([int(i1[0]),int(i2[0]),int(i3[0]),int(i4[0]),int(i5[0])],[p,q,r,s,t]))
                    m=m.to_bytes(1000,'big')
                    if b'ctfshow'in m:
                        print(m)
posted @ 2022-03-01 12:00  hash_hash  阅读(345)  评论(0)    收藏  举报