GDOUCTF_wp


GDOUCTF2023

Absolute_Baby_Encrytpion

古典密码,简单替换,只不过js我不会,自己手动做了密码表……

l1='abcdefghijklmnopqrstuvwxyz0123456789!@#$%^&*()_+-=`~{}[]|:;\"\'<>,.?/'
l2='!1)vm+q0c](}[85$*i>#<?o^-_hwe9gzd~=xj:4b`13t6sn;\'rkp\"&/\\2.%|,@{u7ya'
n=0
c='+}!q")hiim)#}-nvm)i-$#mvn#0mnbm)im#n+}!qnm8)i-$#mvnoc#0nz<$9inm!>-n1:1-nm8)i-$~c58n!}qhij#0[noic##m8nc8n?!8c}w!n]>&'
while True:
    m=''
    n += 1
    for i in c:
        tmp = l1[l2.index(i)]
        m += tmp
    if m.startswith('nssctf{'):
        print(m)
        quit()
    c=m
    print(n,m)

print(m)

babylua

lua还是不会,让bing给我逐行解释一下。

什么密码比赛啊做两题学两门语言

好的,我会尽力解释这段代码的每一行。请看以下的注释:

local flag = ‘’ –这里是你要逆推出的flag – 这一行定义了一个局部变量 flag,用来存储你要加密的字符串,目前为空

local md5 = require(“md5”) – 这一行导入了一个名为 md5 的模块,用来计算字符串的 MD5 哈希值

math.randomseed(os.time()) – 这一行设置了随机数种子,用当前的系统时间作为参数

local function randomStr(len) local rankStr = “” local randNum = 0 for i = 1, len do randNum = math.random(1, 2) if randNum == 1 then rankStr = rankStr … string.char(math.random(65, 90)) elseif randNum == 2 then rankStr = rankStr … string.char(math.random(97, 122)) end end return rankStr end – 这一段定义了一个局部函数 randomStr,用来生成一个指定长度的随机字符串 – 函数内部定义了两个局部变量 rankStr 和 randNum,分别用来存储生成的字符串和随机数 – 函数使用了一个 for 循环,从 1 到 len 遍历 – 每次循环中,先生成一个 1 到 2 的随机数,赋值给 randNum – 如果 randNum 等于 1,就在 rankStr 后面拼接一个 65 到 90 的随机 ASCII 码对应的大写字母 – 如果 randNum 等于 2,就在 rankStr 后面拼接一个 97 到 122 的随机 ASCII 码对应的小写字母 – 最后返回 rankStr

local seed = randomStr(4) local key = md5.sumhexa(md5.sumhexa(seed)) print(key:sub(1,10)) – 这三行调用了 randomStr 函数和 md5 模块的方法,生成了一个十位的十六进制字符串 key,并打印出来 – 首先调用 randomStr(4) 生成一个四位的随机字符串,赋值给局部变量 seed – 然后调用 md5.sumhexa(md5.sumhexa(seed)) 对 seed 进行两次 MD5 哈希运算,并转换为十六进制字符串,赋值给局部变量 key – 最后调用 key:sub(1,10) 截取 key 的前十位,并打印出来

secret = {} – 这一行定义了一个全局变量 secret,用来存储加密后的结果,初始化为空表

for i = 1, #flag do secret[i] = string.byte(flag:sub(i,i)) + string.byte(key:sub(i,i)) end – 这一段使用了一个 for 循环,对 flag 和 key 进行逐位加密,并将结果存入 secret 表中 – 循环从 1 到 #flag 遍历,#flag 表示 flag 的长度 – 每次循环中,先调用 flag:sub(i,i) 截取 flag 的第 i 位字符,然后调用 string.byte() 将其转换为 ASCII 码数值 – 然后调用 key:sub(i,i) 截取 key 的第 i 位字符,然后调用 string.byte() 将其转换为 ASCII 码数值 – 最后将两个数值相加,并赋值给 secret[i]

for i, v in ipairs(secret) do io.write(v, ’ ‘) end – 这一段使用了一个 for 循环,遍历 secret 表中的每个元素,并打印出来 – 循环使用 ipairs 函数按照索引顺序遍历 secret 表,每次循环中得到索

后面因为太长被枪毙了我也看不到,但是已经可以知道加密原理了。

先是随机4个字母,以此用md5生成32位的key,但是只给前十位。

接下来把flag的ASCII值加上md5相应字母的值,得到输出。

md5可以直接爆破出来。

from Crypto.Util.number import *
'''
import itertools
from hashlib import md5
from tqdm import *
import string

st='b5e62abe84'
table = string.ascii_lowercase + string.ascii_uppercase
strlist = itertools.product(table, repeat=4)
print(table)
for i in tqdm(strlist):
	tmp = i[0] + i[1] + i[2] + i[3]
	bru = md5(md5(tmp.encode('utf-8')).hexdigest().encode()).hexdigest()
	if bru.startswith(st):
		print(bru)
	'''
	#data_sha=hashlib.md5((data).encode('utf-8')).hexdigest()
key = 'b5e62abe84bc8afbfd97c91a15aa0867'
c = '200 161 198 157 173 169 199 150 105 163 193 175 173 194 135 131 135 225'
c = c.split()
c = [int(i) for i in c]
d=b''
for i in range(len(c)):
	c[i] -= bytes_to_long((key[i]).encode())
	d += long_to_bytes(c[i])

print(d)

文章作者: v
版权声明: 本博客所有文章除特別声明外,均采用 CC BY 4.0 许可协议。转载请注明来源 v !
  目录