[NSSCTF 2021]招新赛Crypto出题人笔记

Crypto

Crypto1

给了c1,c2,n,以及e1e2 = 3087,又因为3087 = 3337*7 大概率想到模不互素,解题脚本如下

import  gmpy2
from Crypto.Util.number import *

def rsa_gong_N_def(e1,e2,c1,c2,n):
   e1, e2, c1, c2, n=int(e1),int(e2),int(c1),int(c2),int(n)
   s = gmpy2.gcdext(e1, e2)
   s1 = s[1]
   s2 = s[2]
   if s1 < 0:
       s1 = - s1
       c1 = gmpy2.invert(c1, n)
   elif s2 < 0:
       s2 = - s2
       c2 = gmpy2.invert(c2, n)
   m = (pow(c1,s1,n) * pow(c2 ,s2 ,n)) % n
   return int(m)

def de(c, e, n):
   k = 0
   while k<1000:
       mm = c + n*k
       result, flag = gmpy2.iroot(mm, e)
       if True == flag:
           return result
       k += 1

for e1 in range(2,e1e2):
   if e1e2%e1==0:
       e2=e1e2//e1
       c=rsa_gong_N_def(e1, e2, c1, c2, n)
       e=gmpy2.gcd(e1,e2)
       m1=de(c,e,n)
       if m1:
           flag=long_to_bytes(int(m1))
           if b"flag" in flag:
               print(flag)
               break

Crypro2

简单的共模攻击

Crypto3

同NPUCTF 2020 共模攻击:https://www.cnblogs.com/vict0r/p/13292511.html 解题脚本

c1=flag1
c2=flag2
a = c1+c2
b = c1*c2

R.<x>=Zmod(n)[]
f = x^2 - a*x +b
f.small_roots(X=2^400)

Crypto4

由于q = nextPrime(p) , 所以可以yafu直接分解n , 直接拿下

Crypto5

低e , e = 3

Crypto6

var="************************************"
flag='NSSCTF{' + base64.b16encode(base64.b32encode(base64.b64encode(var.encode()))) + '}'
print(flag)

小明不小心泄露了源码,输出结果为:4A5A4C564B36434E4B5241544B5432454E4E32465552324E47424758534D44594C4657564336534D4B5241584F574C4B4B463245365643424F35485649534C584A5A56454B4D4B5049354E47593D3D3D,你能还原出var的正确结果吗?

代码逻辑:base64->base32->base16,反解即可。

from base64 import *
str = '4A5A4C564B36434E4B5241544B5432454E4E32465552324E47424758534D44594C4657564336534D4B5241584F574C4B4B463245365643424F35485649534C584A5A56454B4D4B5049354E47593D3D3D'
print(b64decode(b32decode(b16decode(str.encode()))))

NSSCTF{5e110989-dc43-1bd3-00b4-9009206158fe}

Crypto7

69f7906323b4f7d1e4e972acf4abfbfc,得到的结果用NSSCTF{}包裹。

字符串长度32位,很容易想到为MD5,去在线解密网站https://www.cmd5.com/解密即可。

NSSCTF{md5yyds}

Crypto8

73E-30U1&>V-H965S95]I<U]P;W=E<GT`

这字符串刚开始看可能一头雾水,后面给了提示是uucode,这是一种早期unix系统邮件的加密方式按照固定的算法进行的一种数据变换。

可以用php的convert_uudecode() 函数解密。

<?php
$str = "73E-30U1&>V-H965S95]I<U]P;W=E<GT`";
echo convert_uudecode($str);
?>

NSSCTF{cheese_is_power}

Crypto9

AKKPLX{qv5x0021-7n8w-wr05-x25w-7882ntu5q984}
脚本给你了,去解吧

letter_list = 'ABCDEFGHIJKLMNOPQRSTUVWXYZ'  # 字母表


# 根据输入的key生成key列表
def Get_KeyList(key):
   key_list = []
   for ch in key:
       key_list.append(ord(ch.upper()) - 65)
   return key_list


# 加密函数
def Encrypt(plaintext, key_list):
   ciphertext = ""

   i = 0
   for ch in plaintext:  # 遍历明文
       if 0 == i % len(key_list):
           i = 0
       if ch.isalpha():  # 明文是否为字母,如果是,则判断大小写,分别进行加密
           if ch.isupper():
               ciphertext += letter_list[(ord(ch) - 65 + key_list[i]) % 26]
               i += 1
           else:
               ciphertext += letter_list[(ord(ch) - 97 + key_list[i]) % 26].lower()
               i += 1
       else:  # 如果密文不为字母,直接添加到密文字符串里
           ciphertext += ch
   return ciphertext


# 解密函数
def Decrypt(ciphertext, key):
   plaintext = ""

   i = 0
   for ch in ciphertext:  # 遍历密文
       if 0 == i % len(key_list):
           i = 0
       if ch.isalpha():  # 密文为否为字母,如果是,则判断大小写,分别进行解密
           if ch.isupper():
               plaintext += letter_list[(ord(ch) - 65 - key_list[i]) % 26]
               i += 1
           else:
               plaintext += letter_list[(ord(ch) - 97 - key_list[i]) % 26].lower()
               i += 1
       else:  # 如果密文不为字母,直接添加到明文字符串里
           plaintext += ch
   return plaintext


if __name__ == '__main__':
   print("加密请按D,解密请按E:")
   user_input = input();
   while (user_input != 'D' and user_input != 'E'):  # 输入合法性判断
       print("输入有误!请重新输入:")
       user_input = input()

   print("请输入密钥:")
   key = input()
   while (False == key.isalpha()):  # 输入合法性判断
       print("输入有误!密钥为字母,请重新输入:")
       key = input()

   key_list = Get_KeyList(key)

   if user_input == 'D':
       # 加密
       print("请输入明文:")
       plaintext = input()
       ciphertext = Encrypt(plaintext, key_list)
       print("密文为:\n%s" % ciphertext)
   else:
       # 解密
       print("请输入密文:")
       ciphertext = input()
       plaintext = Decrypt(ciphertext, key_list)
       print("明文为:\n%s" % plaintext)

脚本直接给出来了,直接解密就行,不过需要自行猜一下密钥,密钥是NSS。

NSSCTF{dd5f0021-7a8e-ee05-f25e-7882abc5d984}

Crypto10

AFFPGS{pbatenghyngvbaf!!!},建议直接秒了

这题其实就是对ROT18的考察,ROT家族介绍如下:

ROT5 是 rotate by 5 places 的简写,意思是旋转5个位置,其它皆同。下面分别说说它们的编码方式: ROT5:只对数字进行编码,用当前数字往前数的第5个数字替换当前数字,例如当前为0,编码后变成5,当前为1,编码后变成6,以此类推顺序循环。 ROT13:只对字母进行编码,用当前字母往前数的第13个字母替换当前字母,例如当前为A,编码后变成N,当前为B,编码后变成O,以此类推顺序循环。 ROT18:这是一个异类,本来没有,它是将ROT5和ROT13组合在一起,为了好称呼,将其命名为ROT18。 ROT47:对数字、字母、常用符号进行编码,按照它们的ASCII值进行位置替换,用当前字符ASCII值往前数的第47位对应字符替换当前字符,例如当前为小写字母z,编码后变成大写字母K,当前为数字0,编码后变成符号_。用于ROT47编码的字符其ASCII值范围是33-126,具体可参考ASCII编码

在线网站:https://www.qqxiuzi.cn/bianma/ROT5-13-18-47.php解密即可

NSSCTF{congratulations!!!}

ez_caesar

import base64
def caesar(plaintext):
   str_list = list(plaintext)
   i = 0
   while i < len(plaintext):
       if not str_list[i].isalpha():
           str_list[i] = str_list[i]
       else:
           a = "A" if str_list[i].isupper() else "a"
           str_list[i] = chr((ord(str_list[i]) - ord(a) + 5) % 26 + ord(a) or 5)
       i = i + 1

   return ''.join(str_list)

flag = "*************************"
str = caesar(flag)
print(str)

#str="U1hYSFlLe2R0em1mYWpwc3RiaGZqeGZ3fQ=="

这题是对凯撒密码的加密过程魔改了一下,在移位的时候

str_list[i] = chr((ord(str_list[i]) - ord(a) + 5) % 26 + ord(a) or 5)

与5做了一次或运算,所以解密的时候需要再将字符与5做一次或运算

exp:

import base64


def caesar(plaintext):
   str_list = list(plaintext)
   i = 0
   while i < len(plaintext):
       if not str_list[i].isalpha():
           str_list[i] = str_list[i]
       else:
           a = "A" if str_list[i].isupper() else "a"
           str_list[i] = chr((ord(str_list[i]) - ord(a) + 21) % 26 + ord(a) or 5)
       i = i + 1

   return ''.join(str_list)


str1 = "U1hYSFlLe2R0em1mYWpwc3RiaGZqeGZ3fQ=="
res = caesar(str(base64.b64decode(str1), 'utf-8'))
print(res)

NSSCTF{youhaveknowcaesar}

ez_rsa

p = 1325465431
q = 152317153
e = 65537
计算出d,将d用MD5加密后包裹NSSCTF{}提交

一道基础的rsa,用扩展欧几里得算法求e关于piN的模逆元就行,直接上exp。

def extended_enclid(a, b):
   if b == 0:
       return 1, 0
   else:
       x, y = extended_enclid(b, a % b)
       return y, x - a // b * y


p = 1325465431
q = 152317153
n = p * q
piN = (p - 1) * (q - 1)

e = 65537

print(extended_enclid(e, piN))

将求出来的正整数解43476042047970113用MD5加密后包裹NSSCTF{}即可得到正确的flag。

NSSCTF{08bb8fb628da85923e5734a75ac19ffe}

pigpig

猪圈密码,对照密码表解密即可得flag。

NSSCTF{whenthepigwanttoeat}

traditional

西方的二进制数学的发明者莱布尼茨,从中国的八卦图当中受到启发,演绎并推论出了数学矩
阵,
最后创造的二进制数学。二进制数学的诞生为计算机的发明奠定了理论基础。而计算机现在改

了我们整个世界,改变了我们生活,而他的源头却是来自于八卦图。现在,给你一组由八卦图
方位
组成的密文,你能破解出其中的含义吗?
震坤艮 震艮震 坤巽坤 坤巽震 震巽兑 震艮震 震离艮 震离艮
格式:flag{}

读完题目后,能想到这道题肯定与八卦图有关,于是我们去网上搜索一张八卦图出来,再根据题目八卦图与二进制的关系,观察八卦图,发现每个方位的符号只有一条杠、两条杠两种表现形式,

所以试试看把两条杠当作0,一条杠当作1,转换过来是这样的乾:7 巽:6 坎:2 艮:4 坤:0 震:1 离:5兑:3 。

再与上面的密文对应,得到 104 141 60 61 163 141 154 154 因为每个方位只能表示三位二进制数所以最大值为7,

推测得到的数字是八进制数,转换成10进制得到 68 97 48 49 115 97 108 108 。

看到这些数字,我们很容易联想到ascll码,我们把它转换成字符看看。

s = '68 97 48 49 115 97 108 108'
sum = ''
s1 = s.split(" ")
num = 0
for i in s1:
   sum += chr(int(i))
print(sum)

得到正确的flag。

NSSCTF{Da01sall}

发表评论