2021巅峰极客线上初赛Writeup|Crypto部分全

admin 2021年12月15日04:05:54评论223 views字数 4871阅读16分14秒阅读模式

MedicalImage


 

     利用logistic map加密了图片,首先置换了像素点顺序,然后对像素点进行加密。逆向解密,已知logistic map 为 ,所以这里r等于4 先解密,然后顺序反着换回来得到flag图片。


from PIL import Image
from decimal import *
import numpy as np
import random
getcontext().prec = 20

def f1(x):
    # It is based on logistic map in chaotic systems
    # The parameter r takes the largest legal value
    assert(x>=0)
    assert(x<=1)
    return 4 * x * (1-x)

def f2(x):
    # It is based on logistic map in chaotic systems
    # The parameter r takes the largest legal value
    assert(x>=0)
    assert(x<=1)
    return 4 * x * (1-x)

def f3(x):
    # It is based on logistic map in chaotic systems
    # The parameter r takes the largest legal value
    assert(x>=0)
    assert(x<=1)
    return 4 * x * (1-x)

def encryptImage(path):
    im = Image.open(path)
    size = im.size
    pic  = np.array(im) 
    im.close()
    r1 = Decimal('0.478706063089473894123')
    r2 = Decimal('0.613494245341234672318')
    r3 = Decimal('0.946365754637812381837')
    w,h = size
    for i in range(200):
        r1 = f1(r1)
        r2 = f2(r2)
        r3 = f3(r3)
    const = 10**14
    for x in range(w):
        for y in range(h):
            x1 = int(round(const*r1))%w
            y1 = int(round(const*r2))%h
            r1 = f1(r1)
            r2 = f2(r2)
            pic[y1,x1],pic[y,x] = pic[y,x],pic[y1,x1]
            
    p0 = random.randint(100,104)
    c0 = random.randint(200,204)
    config = (p0,c0)
    for x in range(w):
        for y in range(h):
            k = int(round(const*r3))%256
            k = bin(k)[2:].ljust(8,'0')
            k = int(k[p0%8:]+k[:p0%8],2)
            r3 = f3(r3)
            p0 = pic[y,x]
            c0 = k^((k+p0)%256)^c0
            pic[y,x] = c0
            # pic[y,x] = k ^ (( k + pic[y,x] ) % 256 )^c0

    return pic,size,config

def outputImage(path,pic,size):
    im = Image.new('P', size,'white')
    pixels = im.load()
    for i in range(im.size[0]):
        for j in range(im.size[1]):
            pixels[i,j] = (int(pic[j][i]))

    im.save(path)


def decryptImage(path,config):
    im = Image.open(path)
    size = im.size
    pic  = np.array(im) 
    im.close()
    r1 = Decimal('0.478706063089473894123')
    r2 = Decimal('0.613494245341234672318')
    r3 = Decimal('0.946365754637812381837')
    w,h = size
    for i in range(200):
        r1 = f1(r1)
        r2 = f2(r2)
        r3 = f3(r3)
    const = 10**14
    

    (p0,c0) = config 
    for x in range(w):
        for y in range(h):
            k = int(round(const*r3))%256
            k = bin(k)[2:].ljust(8,'0')
            k = int(k[p0%8:]+k[:p0%8],2)
            r3 = f3(r3)

            enc2 = pic[y,x]
            enc1 = enc2 ^ c0 ^ k
            dec = (enc1 - k) % 256
            pic[y,x] = dec
            p0 = dec
            c0 = enc2

    
    r1l = [r1]
    r2l = [r2]
    for x in range(w):
        for y in range(h):
            r1 = f1(r1)
            r2 = f2(r2)
            r1l.append(r1)
            r2l.append(r2)

    r1ll =r1l[::-1]
    r2ll =r2l[::-1]
    index=1
    for x in range(w-1,-1,-1):
        for y in range(h-1,-1,-1):
            r1 = r1ll[index]
            r2 = r2ll[index]

            x1 = int(round(const*r1))%w
            y1 = int(round(const*r2))%h
            pic[y1,x1],pic[y,x] = pic[y,x],pic[y1,x1]
            index += 1

    return pic,size,config

    
enc_img = 'flag_enc.bmp'
out_im = 'flag.bmp'

# pic,size,_ = encryptImage(enc_img)
# outputImage(out_im,pic,size)

for p0 in range(100,104):
    for c0 in range(200,204):
        config = (p0,c0)
        pic,size, _ = decryptImage(enc_img,config)
        out_im = 'flag'+str(p0)+str(c0)+'.bmp'
        outputImage(out_im,pic,size)


learnSM4


     题目提供两个功能,也能够定位到crypt_hack函数,8次交互能够泄露最开始的两组初始密文,应该要用这两组初始密文逆出密钥,由于最开始四组明文由自己定义,应该是可以逆加密流程,首先反 循环自异或,然后反Sbox,应该可以得到两组轮密钥。但接下来就不会了。

    非预期:此时发现给出了key0的sha256,由于key0是32bit的数字,这是可以在cmd5查出来的(出题人草率了,也许原本只是想让选手确认是否为正确key)。


crtrsa


    dp很小,MRCTF出过,http://www.zbc53.top/archives/82/,套这里的脚本做不出来,卡界了?突然发现这里dp很小,于是可以爆破dp 。

    根据费马小定理,ae·dp-11mod p),所以 ae·dp-1-1kp|n 。所以取最大公约数就能获取 2021巅峰极客线上初赛Writeup|Crypto部分全,进而解密RSA,得到flag。

from tqdm import tqdm
from Crypto.Util.number import *

e = 2953544268002866703872076551930953722572317122777861299293407053391808199220655289235983088986372630141821049118015752017412642148934113723174855236142887
N = 6006128121276172470274143101473619963750725942458450119252491144009018469845917986523007748831362674341219814935241703026024431390531323127620970750816983
flag = 4082777468662493175049853412968913980472986215497247773911290709560282223053863513029985115855416847643274608394467813391117463817805000754191093158289399

from gmpy2 import gcd

'''
for dp in tqdm(range(1<<20,-1,-1)):
    s = e*dp-1
    a = 123
    if gcd(pow(a,s,N)-1,N) != 1:
        print(gcd(pow(a,s,N)-1,N))
        break
'''

p = 88483113499234291234797595363172914275282163218450540253170700235627922981203
q = N//p
d = inverse(e,(p-1)*(q-1))
print long_to_bytes(pow(flag,d,N))



2021巅峰极客线上初赛Writeup|Crypto部分全


如果您有意向加入我们,请留言: ),

或邮件投递简历:[email protected]



本文始发于微信公众号(山石网科安全技术研究院):2021巅峰极客线上初赛Writeup | Crypto部分全

  • 左青龙
  • 微信扫一扫
  • weinxin
  • 右白虎
  • 微信扫一扫
  • weinxin
admin
  • 本文由 发表于 2021年12月15日04:05:54
  • 转载请保留本文链接(CN-SEC中文网:感谢原作者辛苦付出):
                   2021巅峰极客线上初赛Writeup|Crypto部分全https://cn-sec.com/archives/445502.html

发表评论

匿名网友 填写信息