buuctf.crypto 140-160

1、[AFCTF2018]Tiny LFSR

考点:LFSR加密
题解:
(1)题目

import sys
from binascii import unhexlify

if(len(sys.argv)<4):
	print("Usage: python Encrypt.py keyfile plaintext ciphername")
	exit(1)

def lfsr(R, mask):
	output = (R << 1) & 0xffffffffffffffff
	i=(R&mask)&0xffffffffffffffff
	lastbit=0
	while i!=0:
		lastbit^=(i&1)
		i=i>>1
	output^=lastbit
	return (output,lastbit)

R = 0
key = ""
with open(sys.argv[1],"r") as f:
	key = f.read()
	R = int(key,16)
	f.close
	
mask = 0b1101100000000000000000000000000000000000000000000000000000000000

a = ''.join([chr(int(b, 16)) for b in [key[i:i+2] for i in range(0, len(key), 2)]])

f=open(sys.argv[2],"r")
ff = open(sys.argv[3],"wb")
s = f.read()
f.close()
lent = len(s)

for i in range(0, len(a)):
	ff.write((ord(s[i])^ord(a[i])).to_bytes(1, byteorder='big'))

for i in range(len(a), lent):
    tmp=0
    for j in range(8):
        (R,out)=lfsr(R,mask)
        tmp=(tmp << 1)^out
    ff.write((tmp^ord(s[i])).to_bytes(1, byteorder='big'))
ff.close()

题目大概的思路就是用Key对Plain.txt和flag_encode.txt进行异或加密,得到了cipher.txt和flag_encode.txt;那么让cipher.txt和flag_encode.txt;进行异或就能得到key

import codecs
import binascii
from Crypto.Util.strxor import strxor
cip = open('cipher.txt', 'rb').read()
msg = open('Plain.txt', 'rb').read()
bytes_data= strxor(cip, msg)[:len(cip)]
print(binascii.b2a_hex(bytes_data))

得到key为:0123456789abcdef;在得到了key之后,解题就只需要再一次进行异或运算即可

import sys
from binascii import unhexlify
from Crypto.Util.strxor import strxor
import codecs
 
 
key = '0123456789abcdef'
R = int(key, 16)
def lfsr(R, mask):
	output = (R << 1) & 0xffffffffffffffff
	i=(R&mask)&0xffffffffffffffff
	lastbit=0
	while i!=0:
		lastbit^=(i&1)
		i=i>>1
	output^=lastbit
	return (output,lastbit)
 
mask = 0b1101100000000000000000000000000000000000000000000000000000000000
 
cip = open('flag_encode.txt', 'rb').read()
a = ''.join([chr(int(b, 16)) for b in [key[i:i+2] for i in range(0, len(key), 2)]])
#上面这步是将a中的16进制范围内的字符每2个一组,构成0~255范围内的8个字符,然后与密文进行异或运算,密文读入时是'\xaa'的形式
lent = len(cip)
ans = []
 
for i in range(len(a)):
    ans.append(chr((cip[i] ^ ord(a[i]))))
 
for i in range(len(a), lent):
    tmp=0
    for j in range(8):
        (R,out)=lfsr(R,mask)
        tmp=(tmp << 1)^out
        #位移8次得到一个8位的序列,这个序列用于后续的异或运算
    ans.append(chr(tmp ^ cip[i]))
    #原本的加密没有改变信息原文的长度,于是可以对其进行简单异或还原信息
    #cip[i]算作是int类型数据,故可以进行异或运算
 
print(''.join(ans))

在这里插入图片描述

2、[BJDCTF 2nd]老文盲了

考点:拼英解密
题解:
(1)题目

缃奸洤绶犵湐鎿寸仢娣涘尪瑗患鐎幎杌勯稕椹曢硴鍝电湐闉归皾

首先尝试拼音解密;发现就是flag
在这里插入图片描述

BJD{淛匶襫黼瀬鎶軄鶛驕鳓哵}

3、[AFCTF2018]一道有趣的题目

考点:
题解:
加密原理是明文自身每个字节依次与自身的某一个字节异或,与谁异或由space决定;那么我们首先就需要将space爆破出来
参考链接

4、LeftOrRight

考点:二叉树
题解:
(1)题目附件是一个照片;先用010看一下;发现了两串16进制数;转为字符看一下
f09e54c1bad2x38mvyg7wzlsuhkijnop 和905e4c1fax328mdyvg7wbsuhklijznop;根据题目提示知道了前序序列和中序列;现在需要算出后序

# f09e54c1bad2x38mvyg7wzlsuhkijnop
# 905e4c1fax328mdyvg7wbsuhklijznop

def fromFMtoL( mid ):
  global las #全局后序遍历
  global fir #先序遍历
  root = fir[0]  #取出当前树根
  fir = fir[1:]  #取出树根后 先序遍历把根拿出来 下面一个元素做树根
  root_po = mid.find( root ) #在中序遍历当中树根的位置
  left = mid[0:root_po]  #左子树
  right = mid[root_po+1:len(mid)] #右子树
  '''
  后序遍历: 左 右 根 
  先左子树 再右子树 最后跟
  '''
  #有左子树的时候
  if len(left) > 0:
    fromFMtoL( left )
  #有右子树的时候
  if len(right) > 0:
    fromFMtoL( right )
  #树根写进结果
  las += root
if __name__ == "__main__" :
  # fir = input("请输入先序遍历:")   #前序遍历的结果
  # mid = input("请输入中序遍历:")   #中序遍历的结果
  fir = "f09e54c1bad2x38mvyg7wzlsuhkijnop"
  mid = "905e4c1fax328mdyvg7wbsuhklijznop"
  # fir = "ABC"
  # mid = "BAC"
  las = ""
  fromFMtoL( mid )
  print(las)

5、[BJDCTF 2nd]签到-y1ng

考点:真的签到题目
题解:直接base64解密就行

6、[GUET-CTF2019]Uncle Sam

考点:RS-Schmidt-Samoa密码系统
(1)==n=p^2q == dn=1mod(p-1)(p-1)
推导可以算出pq=gcd(a^N*d-an);算出pq;就可以解密出m;直接上exp

from gmpy2 import*
from libnum import*
N =  
#N = p^2*q
d = 
c = 
pq = gcd(pow(2,d*N,N)-2,N)
m = pow(c,d,pq)
print(n2s(m))

7、[NCTF2019]Reverse

考点:三重DES pydes模块解密
题解:参考链接
(1)题目:

汮S賳!Ⅳ?Z_l,?漋& hDa莸&5匼?oZ€|U€骸%#}巴
import os
import pyDes
flag = "NCTF{******************************************}"
key = os.urandom(8)

d = pyDes.des(key)
cipher = d.encrypt(flag.encode())

with open('cipher', 'wb') as f:
    f.write(cipher)
# Leak: d.Kn[10] == [0, 1, 0, 0, 0, 1, 0, 1, 0, 1, 1, 0, 1, 1, 0, 1, 1, 0, 1, 0, 1, 0, 1, 0, 1, 0, 1, 0, 1, 0, 1, 0, 0, 0, 0, 1, 0, 0, 1, 0, 0, 0, 1, 0, 0, 0, 0, 1]

解密

from base64 import b64decode
from itertools import product
from DES import *            # https://github.com/soreatu/Cryptography/blob/master/DES.py
guess_8bit = list(product(range(2), repeat=8))
not_in_PC2 = [9,18,22,25,35,38,43,54]

def re_PC2(sbkey):
    # 48-bit -> 56-bit
    res = [0]*56
    for i in range(len(sbkey)):
        res[PC_2_table[i]-1] = sbkey[i]
    return res # ok

def guess_CiDi10(sbkey, t):
    res = re_PC2(sbkey)
    for i in range(8):
        res[not_in_PC2[i]-1] = guess_8bit[t][i]
    return res # ok

def guess_allsbkey(roundkey, r, t):
    sbkey = [[]]*16
    sbkey[r] = roundkey
    CiDi = guess_CiDi10(roundkey, t)
    Ci, Di = CiDi[:28], CiDi[28:]
    for i in range(r+1,r+16):
        Ci, Di = LR(Ci, Di, i%16)
        sbkey[i%16] = PC_2(Ci+Di)
    return sbkey # ok

def long_des_enc(c, k):
    assert len(c) % 8 == 0
    res = b''
    for i in range(0,len(c),8):
        res += DES_enc(c[i:i+8], k)
    return res

def try_des(cipher, roundkey):
    for t in range(256):
        allkey = guess_allsbkey(roundkey, 10, t)
        plain = long_des_enc(cipher, allkey[::-1])
        if plain.startswith(b'NCTF'):
            print(plain)

if __name__ == "__main__":
    cipher = b64decode(b'm0pT2YYUIaL0pjdaX2wsxwedViYAaBkZA0Rh3bUmNYVclBlvWoB8VYC6oSUjfbDN')
    sbkey10 = [0, 1, 0, 0, 0, 1, 0, 1, 0, 1, 1, 0, 1, 1, 0, 1, 1, 0, 1, 0, 1, 0, 1, 0, 1, 0, 1, 0, 1, 0, 1, 0, 0, 0, 0, 1, 0, 0, 1, 0, 0, 0, 1, 0, 0, 0, 0, 1]
    try_des(cipher, sbkey10)
# b'NCTF{1t_7urn3d_0u7_7h47_u_2_g00d_@_r3v3rs3_1snt}'

8、[Zer0pts2020]ROR

考点:对n取余二进制最后一位不变

chall=open('chall.txt').read().split()
mm=[]
for i in chall:
    mm.append(int(i))
m=''
for i in mm:
    m+=bin(i)[-1]
from Crypto.Util.number import long_to_bytes
m=int(m[::-1],2)
print(long_to_bytes(m))

9、[NewStarCTF 2023 公开赛道]babyrsa

题解:rsa
题解:
(1)分解n分解出11个因子;也就是phi的就算不同

import gmpy2
from Crypto.Util.number import long_to_bytes
# 给定的参数
n = 17290066070594979571009663381214201320459569851358502368651245514213538229969915658064992558167323586895088933922835353804055772638980251328261
e = 65537
c = 14322038433761655404678393568158537849783589481463521075694802654611048898878605144663750410655734675423328256213114422929994037240752995363595
# 分解出的因子
P1 = 3207148519
P2 = 2217990919
P3 = 2370292207
P4 = 3654864131
P5 = 2970591037
P6 = 3939901243
P7 = 2338725373
P8 = 2463878387
P9 = 2923072267
P10 = 2706073949
P11 = 3831680819
P12 = 4278428893
P13 = 2804303069
P14 = 4093178561
P15 = 2794985117
# 计算 phi(n)
phi = 1
for p in [P1, P2, P3, P4, P5, P6, P7, P8, P9, P10, P11, P12, P13, P14, P15]:
    phi *= (p - 1)
# 计算私钥 d
d = gmpy2.invert(e, phi)
# 解密密文
m = pow(c, d, n)
# 将解密结果转换为字节
plaintext = long_to_bytes(m)
print(plaintext)

10、[V&N2020 公开赛]easy_RSA

考点:RSA-光滑数求解
题解:从公式可以得知需求出p,q,r,然后逆元出di,从而解出c,m,直接看代码

from Crypto.Util.number import *
from primefac import * 
import gmpy2
from sympy import *
n=7941371739956577280160664419383740967516918938781306610817149744988379280561359039016508679365806108722198157199058807892703837558280678711420411242914059658055366348123106473335186505617418956630780649894945233345985279471106888635177256011468979083320605103256178446993230320443790240285158260236926519042413378204298514714890725325831769281505530787739922007367026883959544239568886349070557272869042275528961483412544495589811933856131557221673534170105409
d = 7515987842794170949444517202158067021118454558360145030399453487603693522695746732547224100845570119375977629070702308991221388721952258969752305904378724402002545947182529859604584400048983091861594720299791743887521228492714135449584003054386457751933095902983841246048952155097668245322664318518861440
cipher = 1618155233923718966393124032999431934705026408748451436388483012584983753140040289666712916510617403356206112730613485227084128314043665913357106301736817062412927135716281544348612150328867226515184078966397180771624148797528036548243343316501503364783092550480439749404301122277056732857399413805293899249313045684662146333448668209567898831091274930053147799756622844119463942087160062353526056879436998061803187343431081504474584816590199768034450005448200
e = 0x10001
 
# 1. 通过光滑数得到p,光滑数求解因子恰好为505bit位的参数p,继续用光滑数向下求解q,r会发现非常慢,可以通过已知条件求解q和r
p = williams_pp1(n)
# 得知505bit位的p
 
# 2. 继续通过d对p^2的逆元求解出q^2 mod p^2,但这里不是唯一解,因为p^2非素数,所以就要考虑用nthroot求解出q
# 即公式 q_2 = q ^ 2 mod p ^ 2;这里尝试通过暴力枚举k参也能得出q;
q_2 = gmpy2.invert(d, p ** 2)
# Find the solutions to ``x**n = a mod m`` when m is not prime.
q = nthroot_mod(q_2, 2, p ** 2)
 
# 3. 求得r
r = n // p // q
 
# 4. 继续逆元求解出c
fin = (p-1)*(q-1)*(r-1)
di = gmpy2.invert(e, fin)
c = gmpy2.powmod(cipher, di, n)
 
#5. nthroot求解出m
m = nthroot_mod(c, 2, r)
print(long_to_bytes(m))
 
#b'flag{fd462593-25e4-4631-a96a-0cd5c72b2d1b}'
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

巅峰赛2000分以下是巅峰

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值