[N1CTF 2022] solve_pow,baby_N1ES

2023/11/30 9:25:44

周六作了两个N1CTF感觉很难就没做,有些东西只是不懂,不是很难。

solve_pow

这个题就是其一

题目会给出一道2乘幂的题

POW: 2^(2^168650911) mod 14410422756791856006977221261653848398173123908149127966358804284026606184669 = ?

一开始想最后是取模,根据费小有a**(p-1)=1 (mod p),然后用公式求解

powmod(2,pow(2,bit,p-1),p)
#4661732238801194169405982400350387428895918512377690837157075128714991112731

但是这个事有点麻烦,p不是素数,如果乘幂又太大了,后来看别人作的,用了bit_set这个函数,原来都没听说过,因为底是2,直接置bit位就行了

所以正确的解法是

powmod(2,bit_set(0,bit),p)
#36808033546212382710607382805842490500296061506256519355047811358611503260

不过只是当时卡在这了,不有另外一个方法,不用这个函数一样

powmod(2,1<<bit,p)
#36808033546212382710607382805842490500296061506256519355047811358611503260

 

baby_N1ES

这个题都没看到,其实这个题很简单,而且还有更简单的解法。

原题

from N1ES import N1ES
import base64
key = "wxy191iss00000000000cute"
n1es = N1ES(key)
flag = "N1CTF{*****************************************}"
cipher = n1es.encrypt(flag)
print base64.b64encode(cipher) # HRlgC2ReHW1/WRk2DikfNBo1dl1XZBJrRR9qECMNOjNHDktBJSxcI1hZIz07YjVx

和一个N1ES.py的库

# -*- coding: utf-8 -*-
def round_add(a, b):
    f = lambda x, y: x + y - 2 * (x & y)
    res = ''
    for i in range(len(a)):
        res += chr(f(ord(a[i]), ord(b[i])))
    return res


def permutate(table, block):
    return list(map(lambda x: block[x], table))


def string_to_bits(data):
    data = [ord(c) for c in data]
    l = len(data) * 8
    result = [0] * l
    pos = 0
    for ch in data:
        for i in range(0, 8):
            result[(pos << 3) + i] = (ch >> i) & 1
        pos += 1
    return result


s_box = [54, 132, 138, 83, 16, 73, 187, 84, 146, 30, 95, 21, 148, 63, 65, 189, 188, 151, 72, 161, 116, 63, 161, 91, 37,
         24, 126, 107, 87, 30, 117, 185, 98, 90, 0, 42, 140, 70, 86, 0, 42, 150, 54, 22, 144, 153, 36, 90, 149, 54, 156,
         8, 59, 40, 110, 56, 1, 84, 103, 22, 65, 17, 190, 41, 99, 151, 119, 124, 68, 17, 166, 125, 95, 65, 105, 133, 49,
         19, 138, 29, 110, 7, 81, 134, 70, 87, 180, 78, 175, 108, 26, 121, 74, 29, 68, 162, 142, 177, 143, 86, 129, 101,
         117, 41, 57, 34, 177, 103, 61, 135, 191, 74, 69, 147, 90, 49, 135, 124, 106, 19, 89, 38, 21, 41, 17, 155, 83,
         38, 159, 179, 19, 157, 68, 105, 151, 166, 171, 122, 179, 114, 52, 183, 89, 107, 113, 65, 161, 141, 18, 121, 95,
         4, 95, 101, 81, 156, 17, 190, 38, 84, 9, 171, 180, 59, 45, 15, 34, 89, 75, 164, 190, 140, 6, 41, 188, 77, 165,
         105, 5, 107, 31, 183, 107, 141, 66, 63, 10, 9, 125, 50, 2, 153, 156, 162, 186, 76, 158, 153, 117, 9, 77, 156,
         11, 145, 12, 169, 52, 57, 161, 7, 158, 110, 191, 43, 82, 186, 49, 102, 166, 31, 41, 5, 189, 27]


def generate(o):
    k = permutate(s_box, o)
    b = []
    for i in range(0, len(k), 7):
        b.append(k[i:i + 7] + [1])
    c = []
    for i in range(32):
        pos = 0
        x = 0
        for j in b[i]:
            x += (j << pos)
            pos += 1
        c.append((0x10001 ** x) % (0x7f))
    return c


class N1ES:
    def __init__(self, key):
        if (len(key) != 24 or isinstance(key, bytes) == False):
            raise Exception("key must be 24 bytes long")
        self.key = key
        self.gen_subkey()

    def gen_subkey(self):
        o = string_to_bits(self.key)
        k = []
        for i in range(8):
            o = generate(o)
            k.extend(o)
            o = string_to_bits([chr(c) for c in o[0:24]])
        self.Kn = []
        for i in range(32):
            self.Kn.append(map(chr, k[i * 8: i * 8 + 8]))
        return

    def encrypt(self, plaintext):
        if (len(plaintext) % 16 != 0 or isinstance(plaintext, bytes) == False):
            raise Exception("plaintext must be a multiple of 16 in length")
        res = ''
        for i in range(len(plaintext) / 16):
            block = plaintext[i * 16:(i + 1) * 16]
            L = block[:8]
            R = block[8:]
            for round_cnt in range(32):
                L, R = R, (round_add(L, self.Kn[round_cnt]))
            L, R = R, L
            res += L + R
        return res
 

先读题,就是个分段加密,每次原来的左与Kn异或然后左右互换,作32轮。由于Kn是固定的,而且加密是异或,所以round_add并不需要处理,只要反过来作个decrypt就行了

这有个小坑,python 2的程序需要改一下

# -*- coding: utf-8 -*-
def round_add(a, b):   #xor
    f = lambda x, y: x + y - 2 * (x & y)
    res = b''
    for i in range(len(a)):
        #res += chr(f(ord(a[i]), ord(b[i])))
        res += bytes([f(a[i], b[i])])
    return res


def permutate(table, block):
    return list(map(lambda x: block[x], table))


def string_to_bits(data):
    #data = [ord(c) for c in data]
    data = [c for c in data]
    l = len(data) * 8
    result = [0] * l
    pos = 0
    for ch in data:
        for i in range(0, 8):
            result[(pos << 3) + i] = (ch >> i) & 1
        pos += 1
    return result


s_box = [54, 132, 138, 83, 16, 73, 187, 84, 146, 30, 95, 21, 148, 63, 65, 189, 188, 151, 72, 161, 116, 63, 161, 91, 37,
         24, 126, 107, 87, 30, 117, 185, 98, 90, 0, 42, 140, 70, 86, 0, 42, 150, 54, 22, 144, 153, 36, 90, 149, 54, 156,
         8, 59, 40, 110, 56, 1, 84, 103, 22, 65, 17, 190, 41, 99, 151, 119, 124, 68, 17, 166, 125, 95, 65, 105, 133, 49,
         19, 138, 29, 110, 7, 81, 134, 70, 87, 180, 78, 175, 108, 26, 121, 74, 29, 68, 162, 142, 177, 143, 86, 129, 101,
         117, 41, 57, 34, 177, 103, 61, 135, 191, 74, 69, 147, 90, 49, 135, 124, 106, 19, 89, 38, 21, 41, 17, 155, 83,
         38, 159, 179, 19, 157, 68, 105, 151, 166, 171, 122, 179, 114, 52, 183, 89, 107, 113, 65, 161, 141, 18, 121, 95,
         4, 95, 101, 81, 156, 17, 190, 38, 84, 9, 171, 180, 59, 45, 15, 34, 89, 75, 164, 190, 140, 6, 41, 188, 77, 165,
         105, 5, 107, 31, 183, 107, 141, 66, 63, 10, 9, 125, 50, 2, 153, 156, 162, 186, 76, 158, 153, 117, 9, 77, 156,
         11, 145, 12, 169, 52, 57, 161, 7, 158, 110, 191, 43, 82, 186, 49, 102, 166, 31, 41, 5, 189, 27]


def generate(o):
    k = permutate(s_box, o)
    b = []
    for i in range(0, len(k), 7):
        b.append(k[i:i + 7] + [1])
    c = []
    for i in range(32):
        pos = 0
        x = 0
        for j in b[i]:
            x += (j << pos)
            pos += 1
        c.append((0x10001 ** x) % (0x7f))
    return c


class N1ES:
    def __init__(self, key):
        #if (len(key) != 24 or isinstance(key, bytes) == False):
        #    raise Exception("key must be 24 bytes long")
        self.key = key
        self.gen_subkey()

    def gen_subkey(self):
        o = string_to_bits(self.key)
        k = []
        for i in range(8):
            o = generate(o)
            k.extend(o)
            #o = string_to_bits([chr(c) for c in o[0:24]])
            o = string_to_bits([c for c in o[0:24]])
        self.Kn = []
        for i in range(32):
            #self.Kn.append(map(chr, k[i * 8: i * 8 + 8]))
            self.Kn.append(k[i * 8: i * 8 + 8])
        return

    def encrypt(self, plaintext):
        #if (len(plaintext) % 16 != 0 or isinstance(plaintext, bytes) == False):
        #    raise Exception("plaintext must be a multiple of 16 in length")
        res = b''
        for i in range(len(plaintext) // 16):
            block = plaintext[i * 16:(i + 1) * 16]
            L = block[:8]
            R = block[8:]
            for round_cnt in range(32):
                L, R = R, (round_add(L, self.Kn[round_cnt]))
            L, R = R, L
            res += L + R
        return res

    def decrypt(self, plaintext):
        #if (len(plaintext) % 16 != 0 or isinstance(plaintext, bytes) == False):
        #    raise Exception("plaintext must be a multiple of 16 in length")
        res = b''
        for i in range(len(plaintext) // 16):
            block = plaintext[i * 16:(i + 1) * 16]
            L = block[:8]
            R = block[8:]
            for round_cnt in range(32):
                L, R = (round_add(R, self.Kn[round_cnt])), L
            L, R = R, L            
            res += L + R
        return res

然后直接解密

from N1ES import N1ES
import base64

key = b"wxy191iss00000000000cute"
n1es = N1ES(key)
t = base64.b64decode('HRlgC2ReHW1/WRk2DikfNBo1dl1XZBJrRR9qECMNOjNHDktBJSxcI1hZIz07YjVx')
print(n1es.decrypt(t))
#b'N1CTF{F3istel_n3tw0rk_c4n_b3_ea5i1y_s0lv3d_/--/}'

不过今天看了个WP,还有更简单的方法,这个东西是个循环,直接再加密,而且3次就循环,太容易了

for i in range(3):
    t = n1es.encrypt(t)
    print(t)

没作,也没保存确实可惜了,只是那个checkin没作出来。


http://www.jnnr.cn/a/118492.html

相关文章

数据库知识点整合

文章目录数据库系统概论第一章 绪论1.1 数据库的四个基本概念数据库概念小结1.2 数据模型1.2.1 概念1.2.2 组成要素1.2.3 两类数据模型1.2.4 数据库系统的三级模式结构1.2.5 二级映像功能与数据独立性第二章 关系数据库2.1 关系数据库2.2 关系的完整性2.3 关系代数2.3.1 传统的…

微课怎么录制?教师录制微课这样操作,课程更精彩、操作更便捷!

随着疫情的不稳定&#xff0c;许多做教培行业的教师们纷纷将教育事业由线下转至线上来进行&#xff0c;这正是基于此种需求&#xff0c;微课录制成为了重要教学方式。然而很多新手教师并不了解微课怎么录制。今天&#xff0c;小编就为大家分享教培行业怎么录制微课视频吧。 授课…

部署zabbix5.4

安装一个rockylinux系统 安装基础工具 yum -y install wget lrzsz net-tools vim bash-completion tree dos2unix 安装zabbix dnf install https://mirrors.tuna.tsinghua.edu.cn/zabbix/zabbix/5.5/rhel/8/x86_64/zabbix-release-5.5-1.el8.noarch.rpm cd /etc/repos.d/ vim …

Ubuntu22.04.01Desktop桌面版安装记录221109

自定义分区 新建分区表 点击新建的空闲分区, 然后点加号 因为虚拟机设置选了UEFI , 所以先建立一个"EFI系统分区" , 设置大小,来它300兆 继续点 剩下的空闲分区, 再点加号 剩下的空间都个了根分区 / 没有设置 /boot 和 swap 分区, 只为做一下试验, 看能否安装 …

matplotlib 中使用中文

最近帮师兄画图&#xff0c;要求图中的标注必须是中文&#xff0c;我尝试在画图的 python 文件中直接写入中文&#xff0c;但是会报 warning&#xff0c;说找不到对应的字体&#xff1a; /data/hanjl/rl-exercise/common/plot_all.py:226: UserWarning: Glyph 19975 (\N{CJK U…

2023最新SSM计算机毕业设计选题大全(附源码+LW)之java客房订餐系统s2whx

面对老师五花八门的设计要求&#xff0c;首先自己要明确好自己的题目方向&#xff0c;并且与老师多多沟通&#xff0c;用什么编程语言&#xff0c;使用到什么数据库&#xff0c;确定好了&#xff0c;在开始着手毕业设计。 1&#xff1a;选择课题的第一选择就是尽量选择指导老师…

虚拟化设备-Virtio介绍

虚拟化环境必须使用客户操作系统自身的驱动感觉不到自己运行在虚拟机上&#xff0c;不然让客户操作系统开发人员编写大量代码同样不是一个很好的设计方案&#xff0c;因此虚拟化系统需要提供抽象设备&#xff0c;抽象设备实现了针对特定设备类的高级接口&#xff0c;目前比较高…

帧同步和状态同步

网络同步 网络同步主要目的在于保证各个端口的游戏表现一致&#xff0c;网络同步就在于实时的多段数据同步和实时的多端表现。 而对于大多数游戏&#xff0c;不仅客户端的表现要一致&#xff0c;而且需要客户端和服务端的数据是一致的。所以&#xff0c;同步是一个网络游戏概…

[Linux]----文件系统

文章目录前言一、磁盘的物理结构二、磁盘的存储结构三、磁盘的逻辑抽象结构总结前言 之前我们理解到的文件描述符等内容&#xff0c;全部都是在内存中&#xff01;因为文件被访问必须得先加载到内存中&#xff01; 但不是所有的文件都被打开了&#xff0c;还有大量的文件就在磁…

RSA的C++语言描述简单实现

文章目录前言代码特点大&#xff08;素&#xff09;数讨论部分资料作者理解代码rsa.hrsa.cppmain.cpp结果总结参考资料作者的话前言 网络安全中RSA的C语言描述简单实现。 代码特点 纯C语言&#xff1a; 相对规范和整洁一定程度地面向对象使用一部分高级特性考虑优化性能 详…

JVM 的主要组成部分及其作用

JVM包含两个子系统和两个组件&#xff0c;分别为&#xff1a; Class loader(类装载子系统)&#xff1a;根据给定的全限定名类名(如&#xff1a;java.lang.Object)来装载class文件到运行时数据区的方法区中。 Execution engine(执行引擎子系统)&#xff1a;执行class的指令。 Ru…

山东菏泽家乡网页代码 html静态网页设计制作 dw静态网页成品模板素材网页 web前端网页设计与制作 div静态网页设计

家乡旅游景点网页作业制作 网页代码运用了DIV盒子的使用方法&#xff0c;如盒子的嵌套、浮动、margin、border、background等属性的使用&#xff0c;外部大盒子设定居中&#xff0c;内部左中右布局&#xff0c;下方横向浮动排列&#xff0c;大学学习的前端知识点和布局方式都有…

如何做出技术和测试都喜欢的需求文档?

在产品的工作中&#xff0c;需求文档的撰写是我们日常工作中必不可少的一环。很多产品经理会问什么样的需求文档是一篇比较好的文档呢&#xff1f; 你会发现你平常能找到的一些需求文档的模板各不一样&#xff0c;没有什么固定的版式&#xff0c;也没有哪个模板是大家公认的特…

你不知道的JS 之 this this指向

this 关键字是JavaScript中最复杂的机制之一。他是一个很特别的关键字&#xff0c;被自动定义在所有函数作用域中。即使是非常有经验的JavaScript开发者也很难说清楚它到底只想什么。 为什么学习this 1.this提供了一种更优雅的方式来隐式传递一个对象引用让我们写出更具有复用…

小程序意见反馈界面(简洁版代码)

在开发个人中心页面时&#xff0c;意见反馈功能是必不可少的&#xff0c;下面介绍该功能的具体开发流程 1、首先看一下效果图&#xff1a; 2、WXML代码&#xff0c;分为三个部分&#xff0c;文本域&#xff08;TextArea&#xff09;、输入框&#xff08;Input)、按钮&#xff…

软件工程毕业设计课题(14)基于python的毕业设计python运动场地预约系统毕设作品源码

项目背景和意义 目的&#xff1a;本课题主要目标是设计并能够实现一个基于web网页的校园运动场地预约系统通&#xff0c;整个网站项目使用了B/S架构&#xff0c;基于python的Django框架下开发&#xff1b;管理员过后台添加开放的场地类型&#xff08;比如羽毛球、篮球、网球等&…

查找算法.

在java中,常用的查找有四种 顺序查找二分查找/折半查找插值插值斐波拉查找 线性查找算法 有一个数列(1,8,10,89,1000,1234),判断数列中是否包含此名称[顺序查找],要求:如果找到了,就提示找到,并给出下标值, 思路:如果查到全部符合条件的值; 注意我们的线性查找我们找到一个…

学生静态HTML个人博客主页【Web大学生网页作业成品】HTML+CSS+JavaScript

&#x1f389;精彩专栏推荐 &#x1f4ad;文末获取联系 ✍️ 作者简介: 一个热爱把逻辑思维转变为代码的技术博主 &#x1f482; 作者主页: 【主页——&#x1f680;获取更多优质源码】 &#x1f393; web前端期末大作业&#xff1a; 【&#x1f4da;毕设项目精品实战案例 (10…

国产高性能2.92mm小型化同轴固定衰减器

射频衰减器是双向双端口无源器件&#xff0c;是射频和微波系统中最重要的部件之一。常见的衰减电路为PI形衰减电路和T型衰减电路。在许多微波系统&#xff0c;如雷达、多信道通信系统和其他传输损耗和接收信号的测量中都离不开射频衰减器&#xff0c;其性能的好坏直接影响测试的…

css:清除浮动的n种方式

浮动 <!DOCTYPE html> <html lang"en"> <head><style>.header {width: 200px;border: 1px solid #f00;overflow: hidden;}.footer {width: 200;height: 100px;background-color: #000;}.header-big {width: 100px;height: 100px;background…
最新文章