2023第七届河南省高等学校信息安全对抗大赛-御网杯-ISCC2023线下赛-(misc+cryoto)(详解-思路-脚本)

本文主要是介绍2023第七届河南省高等学校信息安全对抗大赛-御网杯-ISCC2023线下赛-(misc+cryoto)(详解-思路-脚本),希望对大家解决编程问题提供一定的参考价值,需要的开发者们随着小编来一起学习吧!

芜湖~

是真累呀  原本一天的时间 硬打了一天半 还是那句话 不评价 各位道友心中自有公论

我misc手又发现一个小小的非预期 哎 没想到线下也有这种情况

欧克 以下是我自己的一些思路和解析 有什么问题或者建议随时都可以联系我

2023第七届河南省高等学校信息安全对抗大赛-御网杯-ISCC2023线下赛

下文我是misc和cryoto的见解和思路

附件下载

链接:https://pan.baidu.com/s/1qaIl_ZJVaBY4Kpnkl3NFMw?pwd=lulu 
提取码:lulu 
--来自百度网盘超级会员V3的分享

目录

Misc

Color

代码解释

Sarilang

看到音频第一步是干啥

补充

Badimages

Cryoto

xor4

脚本解析

上脚本

不安全的公钥

一个字符而已

代码解释

加油各位( •̀ ω •́ )y 期待与君再相逢


Misc

Color

 只有一个txt文件

 当文件打开 里面的文件暴露在我们眼前时 哇哦

我相信很多老手立马就明白怎么做

这就是一道很简单的RGB转图片的题目 更不用说文件名还是个提示

(当然新手就一定要多积累)

这里我们上脚本(带解析)

我们需要写一个脚本 创建一个空白的RGB图像,然后从指定的文件"color.txt"中读取颜色信息,并将这些颜色信息逐个应用于图像的每个像素点。最后,通过im.show()方法显示图像。

from PIL import Image# 定义图像的宽度和高度x = 500y = 500# 创建一个新的RGB图像im = Image.new("RGB", (x, y))# 打开并读取颜色文件file = open("./color.txt", "r")# 遍历图像的每个像素for i in range(x):for j in range(y):# 从文件中读取一行颜色信息,并去除换行符line = file.readline().strip("\n")# 去除括号并分割RGB值line = line.replace("(", "").replace(")", "")rgb = list(line.split(","))# 将颜色值转换为整数,并将RGB值应用到当前像素im.putpixel((i, j), (int(rgb[0]), int(rgb[1].strip(" ")), int(rgb[2].strip(" "))))# 显示图像im.show()

代码解释

上述代码中,我们使用了PIL(Python Imaging Library)库来进行图像处理。具体步骤如下:

  • 引入Image类:我们从PIL库中导入Image模块,这样我们就可以使用其中的函数和方法。
  • 定义图像尺寸:我们使用变量x和y分别指定图像的宽度和高度,这里设置为500。
  • 创建空白图像:通过Image.new()函数创建一个新的RGB图像对象,使用参数"RGB"指定图像的颜色模式为红绿蓝(RGB),并将宽度和高度作为参数传递进去。
  • 打开颜色文件:通过open()函数打开名为"color.txt"的文件,并指定为只读模式。该文件应该包含一系列RGB颜色值,每行一个颜色值。
  • 遍历图像像素:使用嵌套的for循环遍历图像的每个像素点,外层循环控制行数,内层循环控制列数。
  • 读取颜色信息:使用file.readline()函数逐行读取文件中的颜色信息,并通过.strip("\n")方法去除每行末尾的换行符。
  • 解析颜色信息:通过字符串操作去除括号,并使用.split(",")方法将RGB值分割成字符串列表。
  • 转换颜色值:使用int()函数将RGB字符串转换为整数,并分别赋值给red、green和blue变量。
  • 应用颜色信息:通过im.putpixel()方法将RGB值应用到当前遍历到的像素点上,传递参数为当前像素的坐标(i, j)和颜色值(red, green, blue)。
  • 显示图像:通过im.show()方法显示生成的图像。
  • 请确保在运行代码之前,已经准备好了名为"color.txt"的文件,并按照每行一个颜色值的格式进行存储,例如:(255, 0, 0)表示红色。

直接运行得到flag

flag{fb8c67f9-712b-4f3d-9cb2-9219685421a9}

Sarilang

还是只有一个文件 不过这次是一个音频

歌挺好听的 

看到音频第一步是干啥

甲:那它是音频第一步肯定看波形图呀

乙:咦 misc不关什么类型,第一步一定是看文件源码

我:什么 拿到音频第一步不应该是享受歌曲吗? 草原最美的花 火红的撒日朗

欧克欧克 回到正题

其实最开始我也看过波形图 但没有什么用

那我们就从源码看起 010走起

 我们在文件尾发现了很明显的提示

AES加密 密码是12345678

可这是离线状态 断网

我们想想有什么隐写软件 是用AES加密

静默之眼(silenteye) 别问我怎么知道(都是电脑上有的工具试错的) 不过这个工具挺冷门的

 我们选择文件 选择解密

运行得到一个txt的文件(解压过的)

里面是密密麻麻由012组成的编码

我的天 最烦这种了

欧克欧克 现在让我们仔细思考一下

什么编码是用三个字符组成的

这一下子 我还真没想起来几个

不过我们在仔细观察 如果非要转一个字符

0最常变的不就是.

1长的想!

这个2那就是?

那我们直接一手替换

卧槽 不转不知道一转吓一跳 这不是brainfuck编码的变种码

断网 这种要么使用脚本 要么使用离线的工具箱 还好我都有 不愧是一个misc手

python2 ook.py -o 2.txt

 保存到记事板里

再运行一次

python2 ook.py -b 3.txt

得到flag 哎 这个题主打的就是冷门

补充

这里补充一下知识点

Ook! Ook! 是一种通过模仿猩猩语言来表达的编码。它是在Brainfuck基础上衍生出来的一种变体编码。Ook! Ook! 使用三个字符组成,即 "Ook."、"Ook?" 和 "Ook!"。

每个 "Ook!" 表示一个指令。以下是对应关系:

  • "Ook. Ook?":相当于 Brainfuck 中的 "<"
  • "Ook? Ook.":相当于 Brainfuck 中的 ">"
  • "Ook. Ook.":相当于 Brainfuck 中的 "+"
  • "Ook! Ook!":相当于 Brainfuck 中的 "-"
  • "Ook! Ook.":相当于 Brainfuck 中的 "."
  • "Ook. Ook!":相当于 Brainfuck 中的 ","
  • "Ook! Ook?":相当于 Brainfuck 中的 "["
  • "Ook? Ook!":相当于 Brainfuck 中的 "]"

Ook! Ook! 编码的使用方式和含义与 Brainfuck 类似,只是使用了不同的语言描述

Brainfuck是一种由八个字符组成的编码。这种编码是一种极简主义的编程语言,由八个指令符号组成,包括">"、"<"、"+"、"-"、"."、","、"["和"]"。

Badimages

 看看名字 大概意思是坏掉的镜像

盲猜这个题的思路是要恢复里面的一个文件或者数据

但是但是这个题有非预期解  这要是线上又是给我加分

 我直接cat他 哈哈

 在最后 我们发现了flag 直接结束

正常解 也就是我最开始说的思路

感兴趣的可以去试试

后期我要时间 也会上传

Cryoto

xor4

 

只有一个原文件和脚本

这一看 应该就猜到了思路

Flag运行task.py得到cipher

我们需要做的就是把解析脚本 把cipher逆过来 得到flag

下面是task.py 我们先分析一下

脚本解析

 当然,我将详细解析这个脚本的每个部分:

from secret import flag

这行代码从名为 "secret" 的模块中导入了一个变量 flag。根据代码片段提供的信息,我们可以假设 flag 是包含秘密标志的字符串。

import random

这行代码导入了 Python 的内置模块 random,它提供了生成随机数的功能。

k = random.randint(0, 255)

这行代码使用 random.randint() 函数生成一个在区间 [0, 255] 之间(包括边界)的随机整数,并将其赋值给变量 k。这个随机整数将作为 XOR 运算的密钥。

cipher = “”

for c in flag:

    cipher += chr(ord(c) ^ k)

这部分代码使用循环遍历 flag 字符串中的每个字符,并进行以下操作:

  • ord(c) 获取字符 c 的 ASCII 值。
  • 将 ASCII 值与密钥 k 进行异或运算:ord(c) ^ k
  • chr() 函数将结果转换回相应的字符。
  • 最后,将得到的字符追加到 cipher 字符串中。

这样循环执行直到遍历完整个 flag 字符串,生成了经过 XOR 运算后的密文字符串 cipher

with open("cipher", "w") as f:

    f.write(cipher)

这部分代码使用 open() 函数创建一个名为 "cipher" 的文件,并以写入模式打开它。然后,通过 write() 方法将密文字符串 cipher 写入到文件中。最后,使用 with 语句来确保文件操作的正确关闭。

脚本的目标是使用 XOR 运算和随机生成的密钥对秘密标志进行加密,并将生成的密文保存到名为 "cipher" 的文件中。

对flag中的每一个字符都异或上了同一个数字k,进行加密。

明文中的所有字符,都和同一个密钥k进行了异或。

因此,只需要穷举出256钟可能的k,然后尝试去异或解密,如果解密出来的字符串中含有“flag”,则说明解密成功。

上脚本

with open("cipher", "r") as f:cipher = f.read()#打开名为 "cipher" 的文件,并以只读模式打开它for k in range(0, 256):msg = ""#外层循环使用 range(0, 256) 遍历从 0 到 255 的所有可能的密钥for c in cipher:#内层循环遍历 cipher 字符串中的每个字符msg += chr(ord(c) ^ k)#chr() 函数将结果转换回相应的字符。-       #最后,将得到的字符追加到 msg 字符串中,以构建解密后的消息if "flag" in msg:print(msg)break#解密后的消息中包含字符串 "flag",则输出该消息并跳出循环

运行得到flag

flag{c30dd6b0-38a3-5f88-830c-52ed3b67c81f}

不安全的公钥

 一个公钥一个密文

很明显是RSA解密

pem公钥文件可以提取出n和e

而有n,我们就需要费马分解得到p和q,进行rsa解密

当然风儿西的工具应该是我目前了解到离线解rsa最方便的工具了

但脚本还是要有的

# -*- coding: utf-8 -*-from Crypto.PublicKey import RSAfrom gmpy2 import *def Pollard_rho_func_2(a,n):return (pow(a,n-1,n)+3)%nwith open('pub.pem', 'r') as f:key = RSA.importKey(f)print('n:'+str(key.n))print('e:'+str(key.e))n = key.ne = key.e# 费get p,qori=2a=Pollard_rho_func_2(ori,n)b=Pollard_rho_func_2(a,n)p=1i=1while (a!=b):if (gcd(abs(a-b),n)>1):p=gcd(abs(a-b),n)breakelse:a = Pollard_rho_func_2(a,n)b = Pollard_rho_func_2(b,n)b = Pollard_rho_func_2(b,n)i+=1if (i%100==0):print(i)if (p!=1):print('p:'+str(p))q = n/pprint('q:'+str(q))# p= 189749484366449861630736482622030204229600074936733397229668738586605895979811823994029500725448581332746860468289540041125768726148614579255062994177531727784605194094836998282676712435286273497842956368997116036170165393912022560935791934662695453870846024312915604049805219410140420469163797779129644454583# q= 177993461816075408240866752227210319316825574291000376727523991315086097605063837563342286560819823849610146713383370383386260295565108973920944593141677024612114517119831676665456754235233172344362610684938542774386956894066675103840244633202469661725050948177995671009070311486253646420435061175078660441183d = invert(e,(p-1)*(q-1))print('d:'+str(d))#c = 0xc1bb8cbb9581abf710cab1908a04772f6cc972756e161a5a0615eaf1505d6928e545e626a508abd8c008d43c4eab5ee751c2b5e297891784dc851d8ba887907278142bc70649b503fdec092b143f3afc4508e1671f503c8e38d624befdeeea2bfd3e947289000568a2e409d0f955e19ebb9dccb798543c6435247a8d6b05facddb7f270fce1cecf92994beb7f3119d7f09caa4cff46c9e8db119e41726d0a0ce02ab2b5ae42c3e64c17746a29a32bd642a6045d73078ae8bd1f54a869760474b395c493ffc69cd8020647dcb0610779296a7c18aa984c5b74414e45bdf5d44000888765e457fb84e1ba3b6f60f7ab4f3b9047614f36adf49eac5d662c5916fb8c = 0x2093fdefa37b3b4ef0d45f42e32f98aa3f1495f06ef6a24250origin = pow(c,d,n)print('*'*20)print(hex(origin)[2:].decode('hex'))

得到gkce~ow]dDyYsg|]{<}jtcsq

这一看 不是凯撒就是栅栏 因为两个括号都有

有工具可以上工具 但脚本的编写还是要会的

a = "gkce~ow]dDyYsg|]{<}jtcsq"b = ''# 遍历字符串 'a' 中的每个字符for i in range(len(a)):j = i / 2 + 1# 如果索引 'i' 是偶数,则从字符的 ASCII 值中减去 'j'if i % 2 == 0:b += chr(ord(a[i]) - j)else:# 如果索引 'i' 是奇数,则将 'j' 添加到字符的 ASCII 值中b += chr(ord(a[i]) + j)# 打印转换后的字符串 'b'print(b)

在这段代码中,你使用了一个循环来遍历字符串a的每个字符,并通过一些算术运算来对字符进行加密或解密。

具体来说,在加密过程中,你通过将字符的ASCII码减去索引除以2再加1来获得加密后的字符。而在解密过程中,你将字符的ASCII码加上索引除以2来获得原始字符。

根据你提供的字符串"a",

flag{we_l0v3_encrYpti0n}

一个字符而已

 当文件打开的那一刻

这是一个字符吗 这是一堆字符

好烦 好烦

但看到这里 我忽然想到今年iscc线上的一道misc题 AL的那个大题

那个题最后也得到了一个类似上面的文本 他是只有其中一行是真的编码 解码后才是flag

其他的行全是干扰信息

感慨完了 我们继续看这道题

文本全部是16进制表示

可以将所有字符转换成ascii看下内容

但发现转换完后输出都是乱码

 题目的名称是一个字符而已 

结合以往经验和线上的相似题 猜测是异或加密 且正确答案是其中一行使用某个字符异或后的结果 

思路不出意外应该是这,但如果真的一个一个去手解 怕整个线下的时间都不够

由于不知道秘钥是否是可见字符 所以可以使用0,255循环解密所有内容

 因为文件一共有500行,每一行使用255此解密,最终输出的结果为500*255=127500行,就算正确的结果在其中,我们也很难用眼睛逐行查看。

因为最终的flag肯定可读ascii码,所以我们筛选出所有结果中的数字、字母、空格组合的结果

这是一个大致的思路

后面会给脚本的具体解释

#coding:utf-8import binascii# 将16进制转换为ASCIIdef hex2char(data):output = binascii.unhexlify(data)return output# 异或解密函数,tips为加密字符串,key为秘钥,长度可变def xor_encrypt(tips, key):lkey = len(key)secret = []num = 0for each in tips:if num >= lkey:num = num % lkey# 将每个字符与秘钥进行异或运算,并将结果转换为ASCII字符secret.append(chr(ord(each) ^ ord(key[num])))num += 1# 将解密后的字符列表连接成字符串并返回return "".join(secret)# 打开文件并读取所有行的内容txt = open('enc.txt', 'r').readlines()# 遍历文件中的每一行for line in txt:# 尝试使用0到255之间的不同整数作为秘钥进行解密操作for i in range(0, 255):a = 1result = xor_encrypt(hex2char(line.strip('\n')), chr(i))# 筛选出只包含数字、字母和空格的解密结果for j in result.strip('\n'):k = ord(j)# 如果字符不是数字、字母或空格,则将标志a设置为0if k < ord('z') + 1 and k > ord('0') - 1:passelif k == 32:passelse:a = 0break# 如果解密结果只包含数字、字母和空格,则打印该结果if a == 1:print(result)# python2

代码解释

当你运行这段代码时,它会尝试解密一个名为'enc.txt'的输入文件中的每一行内容。

首先,代码定义了两个函数:

1.hex2char(data)函数使用binascii模块将十六进制数据转换为ASCII字符串。

  • 它接受一个参数data,表示要转换的十六进制数据。
  • 函数内部调用binascii.unhexlify()函数来执行转换操作。
  • 最后,将转换后的ASCII字符串作为结果返回。2.

2.xor_encrypt(tips, key)函数执行异或加密和解密操作。

  • 它接受两个参数:tips表示要加密或解密的字符串,key表示密钥。
  • 函数内部定义了一些变量:lkey表示密钥的长度,secret用于存储加密或解密的结果,num用于跟踪密钥中的字符位置。
  • 函数通过逐个字符地对密钥和输入字符串执行异或运算来进行加密或解密。如果密钥长度不足,则循环使用密钥中的字符。
  • 异或运算通过将字符转换为ASCII码,执行异或操作,然后将结果转换回字符形式来实现。
  • 最后,函数将所有结果字符拼接为一个字符串并返回。

接下来,我们来分析主要的代码逻辑:

  1. txt = open('enc.txt', 'r').readlines():打开名为'enc.txt'的文件并读取所有行,将每一行作为一个字符串存储在txt列表中。
  2. for line in txt::遍历txt列表中的每一行(即文件中的每一行内容)。
  3. for i in range(0, 255)::对于整数值从0到254(ASCII码范围)进行循环,这些值代表可能的密钥字符。
  4. a = 1:初始化变量a为1,用于标记解密结果是否符合筛选条件。
  5. result = xor_encrypt(hex2char(line.strip('\n')), chr(i)):将当前行内容去除换行符,并将其转换为ASCII字符串。然后,使用当前循环中的密钥字符调用xor_encrypt()函数来解密当前行内容,并将解密结果存储在result变量中。
  6. 接下来,通过以下步骤对解密结果进行筛选:
  • for j in result.strip('\n')::对解密结果中的每个字符进行循环处理。
  • k = ord(j):获取字符j的ASCII码,并将其存储在k变量中。
  • 检查字符的ASCII码是否满足以下条件:
  • if k < ord('z') + 1 and k > ord('0') - 1: pass:字符是数字或字母之间的ASCII码范围,继续循环。
  • elif k==32: pass:字符是空格的ASCII码,继续循环。
  • else: a = 0; break:如果字符既不是数字和字母,也不是空格,则将变量a设置为0,并跳出内部循环。

7.if a == 1: print(result):在完成内部循环后,检查变量a的值是否为1。如果是,则表示解密结果符合筛选条件,将其打印输出。\ 

运行得到flag 最好是python2的环境

flag{leKwFMfjcEitrqoTmdkIZSPRVLYxWsQU}

加油各位( •̀ ω •́ )y 期待与君再相逢

这篇关于2023第七届河南省高等学校信息安全对抗大赛-御网杯-ISCC2023线下赛-(misc+cryoto)(详解-思路-脚本)的文章就介绍到这儿,希望我们推荐的文章对编程师们有所帮助!


原文地址:https://blog.csdn.net/m0_68012373/article/details/131585500
本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.chinasem.cn/article/350788

相关文章

Python中的魔术方法__new__详解

《Python中的魔术方法__new__详解》:本文主要介绍Python中的魔术方法__new__的使用,具有很好的参考价值,希望对大家有所帮助,如有错误或未考虑完全的地方,望不吝赐教... 目录一、核心意义与机制1.1 构造过程原理1.2 与 __init__ 对比二、核心功能解析2.1 核心能力2.2

在PyCharm中安装PyTorch、torchvision和OpenCV详解

《在PyCharm中安装PyTorch、torchvision和OpenCV详解》:本文主要介绍在PyCharm中安装PyTorch、torchvision和OpenCV方式,具有很好的参考价值,... 目录PyCharm安装PyTorch、torchvision和OpenCV安装python安装PyTor

SpringBoot条件注解核心作用与使用场景详解

《SpringBoot条件注解核心作用与使用场景详解》SpringBoot的条件注解为开发者提供了强大的动态配置能力,理解其原理和适用场景是构建灵活、可扩展应用的关键,本文将系统梳理所有常用的条件注... 目录引言一、条件注解的核心机制二、SpringBoot内置条件注解详解1、@ConditionalOn

Qt spdlog日志模块的使用详解

《Qtspdlog日志模块的使用详解》在Qt应用程序开发中,良好的日志系统至关重要,本文将介绍如何使用spdlog1.5.0创建满足以下要求的日志系统,感兴趣的朋友一起看看吧... 目录版本摘要例子logmanager.cpp文件main.cpp文件版本spdlog版本:1.5.0采用1.5.0版本主要

Linux ls命令操作详解

《Linuxls命令操作详解》通过ls命令,我们可以查看指定目录下的文件和子目录,并结合不同的选项获取详细的文件信息,如权限、大小、修改时间等,:本文主要介绍Linuxls命令详解,需要的朋友可... 目录1. 命令简介2. 命令的基本语法和用法2.1 语法格式2.2 使用示例2.2.1 列出当前目录下的文

MySQL中的交叉连接、自然连接和内连接查询详解

《MySQL中的交叉连接、自然连接和内连接查询详解》:本文主要介绍MySQL中的交叉连接、自然连接和内连接查询,具有很好的参考价值,希望对大家有所帮助,如有错误或未考虑完全的地方,望不吝赐教... 目录一、引入二、交php叉连接(cross join)三、自然连接(naturalandroid join)四

Go 语言中的select语句详解及工作原理

《Go语言中的select语句详解及工作原理》在Go语言中,select语句是用于处理多个通道(channel)操作的一种控制结构,它类似于switch语句,本文给大家介绍Go语言中的select语... 目录Go 语言中的 select 是做什么的基本功能语法工作原理示例示例 1:监听多个通道示例 2:带

mysql的基础语句和外键查询及其语句详解(推荐)

《mysql的基础语句和外键查询及其语句详解(推荐)》:本文主要介绍mysql的基础语句和外键查询及其语句详解(推荐),本文给大家介绍的非常详细,对大家的学习或工作具有一定的参考借鉴价值,需要的朋... 目录一、mysql 基础语句1. 数据库操作 创建数据库2. 表操作 创建表3. CRUD 操作二、外键

Spring Boot项目部署命令java -jar的各种参数及作用详解

《SpringBoot项目部署命令java-jar的各种参数及作用详解》:本文主要介绍SpringBoot项目部署命令java-jar的各种参数及作用的相关资料,包括设置内存大小、垃圾回收... 目录前言一、基础命令结构二、常见的 Java 命令参数1. 设置内存大小2. 配置垃圾回收器3. 配置线程栈大小

鸿蒙中@State的原理使用详解(HarmonyOS 5)

《鸿蒙中@State的原理使用详解(HarmonyOS5)》@State是HarmonyOSArkTS框架中用于管理组件状态的核心装饰器,其核心作用是实现数据驱动UI的响应式编程模式,本文给大家介绍... 目录一、@State在鸿蒙中是做什么的?二、@Spythontate的基本原理1. 依赖关系的收集2.