vsCTF Crypto wp

本文详细介绍了两个信息安全领域的挑战:一个是基于字符串操作和数学逻辑的密码验证,通过分析代码逻辑和使用base64解码还原密码;另一个是RSA加密问题,利用数学原理和SageMath进行解密。解题过程展示了密码学在实际问题中的应用。
摘要由CSDN通过智能技术生成

真的是让有些同学给我装到了在这里插入图片描述
(狗头保命)vsCTF写到知识库里就没再管,今天看着他的博客,萌生写自己CSDN博客的想法。

Recovery

原题是这样的:

# I coded this so that I wouldn't have to use a database!
from random import randint
from base64 import b64encode

def validate(password: str) -> bool:
    if len(password) != 49:
        return False

    key = ['vs'.join(str(randint(7, 9)) for _ in range(ord(i))) + 'vs' for i in password[::-2]]
    gate = [118, 140, 231, 176, 205, 480, 308, 872, 702, 820, 1034, 1176, 1339, 1232, 1605, 1792, 782, 810, 1197, 880,
            924, 1694, 2185, 2208, 2775]
    if [randint(a, b[0]) for a, b in enumerate(zip(gate, key), 1) if len(b[1]) != 3 * (b[0] + 7 * a) // a]:#保障是个空列表

        return False
    
    #password = 'vsctf{ h 5 _ L G _ 3 3 i s d _ O _ h _ H L _ 1 3}'
    hammer = {str(a): password[a] + password[a + len(password) // 2] for a in range(1, len(password) // 2, 2)}
    block = b'c3MxLnRkMy57XzUuaE83LjVfOS5faDExLkxfMTMuR0gxNS5fTDE3LjNfMTkuMzEyMS5pMzIz'
    if b64encode(b'.'.join([((b + a).encode()) for a, b in hammer.items()])) != block:
        return False

    return True


if __name__ == "__main__":
    passwd = input('Please validate your ID using your password\n> ')
    if validate(passwd):
        print('Access Granted: You now have gained access to the View Source Flag Vault!')
    else:
        print('Access Denied :(')

一点点小思路:
条件if len(password) != 49: return False 可推知password 的长度为49

条件if b64encode(b’.'.join([((b + a).encode()) for a, b in hammer.items()])) == block return False

先将block的内容base64解码得到block_decode, 根据对应关系反向解出hammer,进而根据位置关系将password还原出偶数位

根据条件if [randint(a, b[0]) for a, b in enumerate(zip(gate, key), 1) if len(b[1]) != 3 * (b[0] + 7 * a) // a]:#保障是个空列表 return False 利用gate和长度关系还原奇数字母
解题脚本是这样的

from base64 import b64decode
password = [" " for _ in range(49)]
block = b'c3MxLnRkMy57XzUuaE83LjVfOS5faDExLkxfMTMuR0gxNS5fTDE3LjNfMTkuMzEyMS5pMzIz'
block_decode = b64decode(block).decode()
hammer = { int(i[2:]):i[0]+i[1] for i in block_decode.split('.')}
for i in hammer:
    password[i] = hammer[i][0]
    password[i+49//2] = hammer[i][1]
gate = [118, 140, 231, 176, 205, 480, 308, 872, 702, 820, 1034, 1176, 1339, 1232, 1605, 1792, 782, 810, 1197, 880, 924, 1694, 2185, 2208, 2775]
for i in range(0,len(gate)):
    password[48-2*i] = (chr((gate[i] + 7 * (i+1)) // (i+1)))
print(''.join(password))

Baby RSA

原题是这样的:

from Crypto.PublicKey import RSA
from Crypto.Util.number import *
from secret import e

with open("flag.txt",'r') as f:
    flag = f.read().strip()

p = getPrime(128)
q = getPrime(128)

while p % e != 1:
    p = getPrime(128)
while q % e != 1:
    q = getPrime(128)

n = p * q
m = bytes_to_long(flag.encode())
c = pow(m, e, n)
print(f"Ciphertext: {hex(c)}")

with open("pubkey.pem",'w') as f:
    pk = RSA.construct([n, e])
    f.write(pk.exportKey('PEM').decode('utf-8'))

# Ciphertext: 0x459cc234f24a2fb115ff10e272130048d996f5b562964ee6138442a4429af847
e = 101
n = 52419317100235286358057114349639882093779997394202082664044401328860087685103
p = 184980129074643957218827272858529362113
q = 283378097758180413812138939650885549231
c = 0x459cc234f24a2fb115ff10e272130048d996f5b562964ee6138442a4429af847

可能会有些人问还有一个文件咋没放,之恶能说空间有限,把另一个文件读取出来写在第一个文件最后了。
一点点小思路:
题目的e,n,c是直接给出的,且n是相对较小的,可以通过分解获得p,q,但是存在以下关系

e ∣ ϕ ( n ) e | \phi(n) eϕ(n)

使得不存在d,满足

e × d ≡ 1 ( m o d    n ) e \times d \equiv 1 (\mod n) e×d1(modn)

只能是将方程

m e ≡ c ( m o d    n ) m^e \equiv c (\mod n) mec(modn)

化为

m e ≡ m 1 e ≡ c ( m o d    p ) m e ≡ m 2 e ≡ c ( m o d    q ) m^e \equiv m_1^e \equiv c (\mod p) \newline m^e \equiv m_2^e \equiv c (\mod q) mem1ec(modp)mem2ec(modq)

利用sagemath在有限域上开n次方获得e个 m 1 m_1 m1 和e个 m 2 m_2 m2(不得不说sagemath是真的方便,完全不用自己写AMM算法,真的是棒极了),根据中国剩余定理可获得 e 2 e^2 e2 个m的值

m ≡ m 1 ( m o d    p ) m ≡ m 2 ( m o d    q ) m \equiv m_1 (\mod p ) \newline m\equiv m_2 (\mod q) mm1(modp)mm2(modq)

根据一定条件筛选即可获得明文

解题脚本来了

#sagemath脚本
# 一定要看好哦
from libnum import n2s
e = 101
n = 52419317100235286358057114349639882093779997394202082664044401328860087685103
p = 184980129074643957218827272858529362113
q = 283378097758180413812138939650885549231
c = 0x459cc234f24a2fb115ff10e272130048d996f5b562964ee6138442a4429af847

P.<m> = PolynomialRing(Zmod(p),implementation='NTL')
f = m^e - c;f
m1 = f.monic().roots()
P.<m> = PolynomialRing(Zmod(q),implementation='NTL')
f = m^e - c;f
m2 = f.monic().roots()
m1 = [int(i[0]) for i in m1]
m2 = [int(i[0]) for i in m2]
text_num = []
for i in m1:
    for j in m2:
        try:
            text_num.append(crt([i,j],[p,q]))
        except:
            continue
for i in text_num:
    txt = n2s(int(i))
    if "vsctf" in str(txt):
        print(txt)
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值