当前位置: 首页 > article >正文

[RITSEC CTF 2025] Crypto

这个忘打了,难度不小。

Alien Encryption 101

一个很小的RSA,略

Cuwves 2 Electric Boogaloo

已知p,在p^2下的两个椭圆曲线的j不变量,直接用函数

Mothership

AES_CBC加密给出密文和IV,通过调整IV来修改明文

import base64
import os
import signal

from Crypto.Cipher import AES
from Crypto.Util.Padding import pad, unpad

COORDS = open("coordinates.txt").read().strip()


def encrypt(message, key, iv):
    cipher = AES.new(key, AES.MODE_CBC, iv)
    padded = pad(message.encode(), AES.block_size)
    ciphertext = cipher.encrypt(padded)
    return base64.b64encode(iv + ciphertext).decode()


def validate(data, key):
    try:
        data = base64.b64decode(data)
        iv = data[:16]
        ciphertext = data[16:]
        cipher = AES.new(key, AES.MODE_CBC, iv)
        decrypted = unpad(cipher.decrypt(ciphertext), AES.block_size).decode()

        return decrypted == "SHIP:FIRE"
    except:
        print("Invalid transmission.")
        raise SystemExit(1)


def main():
    print("=== Alien Transmission System ===")
    print("Welcome to the transmission system.")

    signal.alarm(11)
    for i in range(200):
        key = os.urandom(16)
        iv = os.urandom(16)

        print("\nSAFE TRANSMISSION:", encrypt("SHIP:SAFE", key, iv))
        data = input("SEND TRANSMISSION: ")
        if not validate(data, key):
            print("Safe transmission received. Exiting.")
            return
        print(f"Attack transmission received ({i + 1}/200). Continue to confirm.")

    print("Attack mode initiated. Ship coordinates:", COORDS)


if __name__ == "__main__":
    main()
from base64 import b64encode,b64decode
from pwn import *
context.log_level = 'debug'

p = remote('mothership.ctf.ritsec.club', 31750)

for i in range(200):
    p.recvuntil(b':')
    enc = b64decode(p.recvline().strip().decode())
    niv = xor(enc[:16], b'SHIP:FIRE'.ljust(16,b'\0'), b'SHIP:SAFE'.ljust(16,b'\0'))
    p.sendline(b64encode(niv+enc[16:]))

p.recvline()
p.interactive()

不过这个远程有计时,而速度又很慢最多到195总是到不了200

Leaky ZKP

又一个脑筋急转弯的题。前一半看似DLP,p不是strong的,所以可以出来小因子,解出小模下的解,多次可以得到flag。后一半看是hnp (B*x+t = A)其中B自己输入,A给出。问题是这里没有取模,所以当B输入大值时,就能忽略t 

#!/usr/local/bin/python

from os import urandom, getenv
from secrets import randbelow
from Crypto.Util.number import getPrime, bytes_to_long

FLAG = getenv('FLAG', 'MetaCTF{test_flag}').encode()

def main():
    p = getPrime(512)
    k = 32
    x = bytes_to_long(FLAG + urandom(64 - len(FLAG)))
    g = 3
    h = pow(g, x, p)

    print('Let me prove to you in *zero-knowledge* that I know the discrete log of h!')
    print(f'{p = }')
    print(f'{g = }')
    print(f'{h = }')

    # 1. Prover (me) chooses random r_i for i = 1, 2, ..., k and sends each g^r_i
    R = [randbelow(p) for _ in range(k)]
    print([pow(g, r_i, p) for r_i in R])

    # 2. Verifier (you) chooses and sends random bits b_i for i = 1, 2, ..., k
    B = [int(b_i) for b_i in input(f'Send b_1, b_2, ..., b_{k}: ').split(',')]
    assert len(B) == k and all(b_i >= 0 for b_i in B)

    # 3. Prover (me) computes z_i = r_i + b_i x for i = 1, 2, ..., k and sends each z_i
    Z = [r_i + b_i * x for r_i, b_i in zip(R, B)]
    print(Z)

    # 4. Verifier (you) has sufficient information to be convinced that I truly know the discrete log!
    print('With that, you can verify that I know the discrete log, and you will have learnt nothing about my secret!')

if __name__ == '__main__':
    main()

输入 [2**512]+[1]*31拿第1个结果直接右移512位即可。

Bitstream Breach

这个就算没作完(代码太多,略)

给了一堆看不懂的代码。大概看懂以后加密分4部分

1,把64位key转为key1,再key1转为key2,再转为key3由于key已知所以这3个已知

2,把输入进行换位

3,作3轮 l,r=>r,r^k^l 每次用1个key

4,把结果进行第2次换位

看似不难,可转来转去,不知道该提交啥。

#keygen
key = 0xFEDCBA9876543210
skey = bin(key)[2:]
#keycompress 64->32
cp = [10,35,38,13,3,60,9,62,7,43,45,44,34,12,54,24,26,42,41,18,8,31,50,32,17,56,47,0,46,49,27,48]
#kp
kp = [31,11,22,25,21,28,0,19,12,14,17,10,6,9,20,18,24,1,7,26,23,15,27,4,29,5,2,3,30,16,13,8]
#ip
ip = [57,49,41,33,25,17,9,1,59,51,43,35,27,19,11,3,61,53,45,37,29,21,13,5,63,55,47,39,31,23,15,7,56,48,40,32,24,16,8,0,58,50,42,34,26,18,10,2,60,52,44,36,28,20,12,4,62,54,46,38,30,22,14,6]
#fp
fp = [39,7,47,15,55,23,63,31,38,6,46,14,54,22,62,30,37,5,45,13,53,21,61,29,36,4,44,12,52,20,60,28,35,3,43,11,51,19,59,27,34,2,42,10,50,18,58,26,33,1,41,9,49,17,57,25,32,0,40,8,48,16,56,24]
#31 30 ... 0 从高位到低位
kcomp_s = ''.join([skey[63-cp[i]] for i in range(32)])[::-1]

key1 = kcomp_s
krot1_s = kcomp_s[-21:]+ kcomp_s[:11]


kperm1_s = ''.join([krot1_s[31-kp[i]] for i in range(32)])[::-1]
key2 = kperm1_s

krot2_s = kperm1_s[-6:]+kperm1_s[:-6]

key3 = ''.join([krot2_s[31-kp[i]] for i in range(32)])[::-1]


def sxor(a,b):
    return ''.join([str(int(a[i])^int(b[i])) for i in range(32)])



enc = 0x3EA8A2CD3A1C7DE221A48BAD307C7DDA
senc = bin(enc)[2:].zfill(128)
#0x920bd05154bc2173ee3b75d17d3c2193

后边就更看不懂了。


http://www.kler.cn/a/611615.html

相关文章:

  • vscode 通过Remote-ssh远程连接服务器报错 could not establish connection to ubuntu
  • 使用react 引入相对路径文件
  • 学习日记0327
  • xxljob阻塞处理策略设置为单机串行导致的bug
  • PyTorch 深度学习实战(22):多智能体强化学习(MARL)
  • 堆的常见应用2
  • 3.27【A】cv homework
  • 手撕LRU缓存Java版(带输入输出)
  • 《基于机器学习发电数据电量预测》开题报告
  • 学习本地部署DeepSeek的过程(基于LM Studio)
  • 自然语言处理|金融舆情解析:智能事件抽取与风险预警之道
  • 算法-动态规划三
  • 学习threejs,使用Sprite精灵、SpriteMaterial精灵材质
  • 企业内训|DeepSeek技术革命、算力范式重构与场景落地洞察-某头部券商
  • 精选10个好用的WordPress免费主题
  • ELK stack基础架构
  • Android TextView实现跑马灯效果性能优化
  • 用shell脚本,批量备份MySQL中所有数据库,并批量还原!
  • asp.net进销存软件WEB进销存ERP软件库存玻璃行业
  • SQLite优化实践