WP-3-4
WP-3-4
Begin-real checkin xor
签到题:
def xor_decrypt(encrypted, key):
decrypted = [chr(char ^ ord(key[i % len(key)])) for i, char in enumerate(encrypted)]
return ''.join(decrypted)
secret = [7, 31, 56, 25, 23, 15, 91, 21, 49, 15, 33, 88, 26, 48, 60, 58, 4, 86, 36, 64, 23, 54, 63, 0, 54, 22, 6, 55, 59, 38, 108, 39, 45, 23, 102, 27, 11, 56, 32, 0, 82, 24]
key = "ez_python_xor_reverse"
decrypted_result = xor_decrypt(secret, key)
print(decrypted_result)
begin{3z_PY7hoN_r3V3rSE_For_TH3_Be9inNEr!}
Begin-红白机
附件文件名就提醒了是6502汇编语言,注意要和8086处理器区分,6502处理器是一种8位微处理器,主要用于早期的个人计算机和游戏机,也就是题目上的红白机也是。而8086处理器是Intel推出的16位微处理器,用于早期的个人计算机,如IBM PC。网上直接搜的出来的一般都是8086处理器。
一般这种用在线的汇编模拟器来解决:MOS 6502 Simulator,而8086的是:8086 Compiler
解出来就是:flag{6502_I_LOVE_u}
Ps: 这里附上区分6502和8086的方法:
6502汇编语言:
常见的寄存器:A、X、Y等
6502处理器的指令集相对较小,具有约56条指令,主要包括数据传输、算术运算、逻辑运算、分支和跳转等基本操作。
典型指令包括 LDA(加载寄存器A)、STA(存储寄存器A)、LDX(加载寄存器X)、STX(存储寄存器X)、CMP(比较)、BNE(分支不等于零)等。
8086汇编语言:
常见的寄存器:AX、BX、CX、DX等
8086处理器的指令集较为丰富,包括数据传输、算术逻辑运算、字符串操作、输入输出操作、控制转移等多种类型的指令。
典型指令包括 MOV(数据传输)、ADD(加法)、SUB(减法)、INC(递增)、DEC(递减)、CMP(比较)、JMP(无条件跳转)、JZ(零标志位跳转)等。
Begin-ezpython
用PyInstaller Extractor和在线还原得:
#!/usr/bin/env python
# visit https://tool.lu/pyc/ for more information
# Version: Python 3.8
from gmssl import sm4
from secret import key, enc
import base64
def pad_pkcs7(data):
'''PKCS#7填充'''
padding_len = 16 - len(data) % 16
padding = bytes([
padding_len] * padding_len)
return data + padding
def unpad_pkcs7(padded_data):
'''PKCS#7去填充'''
padding_len = padded_data[-1]
return padded_data[:-padding_len]
class SM4:
def __init__(self):
self.gmsm4 = sm4.CryptSM4()
def encryptSM4(self, encrypt_key, value):
gmsm4 = self.gmsm4
gmsm4.set_key(encrypt_key.encode(), sm4.SM4_ENCRYPT)
padded_value = pad_pkcs7(value.encode())
encrypt_value = gmsm4.crypt_ecb(padded_value)
return base64.b64encode(encrypt_value)
if __name__ == '__main__':
print('请输入你的flag:')
flag = input()
sm4_instance = SM4()
flag_1 = sm4_instance.encryptSM4(key, flag)
if flag_1 != enc:
print('flag错误!!')
else:
print('恭喜你获得flag😊😀')
直接运行会报错,因为它无法导入包含 key
and enc
变量的 secret
模块。
然后就又回到一开始解的包里面找secret
模块,因为一开始用PyInstaller Extractor没有直接提取出来就只能用pyi-archieve_viewer手动一个个提取出来:
? o PYZ-00.pyz
//找到PYZ的包,然后在里面有:
Contents of 'PYZ-00.pyz' (PYZ):
//就在里面可以看到:
0, 423121, 188, 'secret'
//提取一下
? x secret
Output filename? secret.pyc
注意我们这里用pyi-archieve_viewer提取的不能直接编译,要加上PyInstaller Extractor中提的pyc的文件头“55 0D 0D 0A 00 00 00 00 00 00 00 00 00 00 00 00”来修补文件头。出来的如下就有了key 和 enc。(对了这里推荐用这个网站https://www.lddgo.net/string/pyc-compile-decompile,之前搜出来的第一个不知道为毛有限制)
# Visit https://www.lddgo.net/string/pyc-compile-decompile for more information
# Version : Python 3.8
key = 'BeginCTFBeginCTF'
enc = b'JmjJEAJGMT6F9bmC+Vyxy8Z1lpfaJzdEX6BGG/qgqUjUpQaYSON1CnZyX9YXTEClSRYm7PFZtGxmJw6LPuw1ww=='
但是这里还不够,写解密脚本会报错。
因为key被加密过,在刚刚的PYZ的包里面就可以看到一个名为gmssl.sm4的文件:
0, 249749, 3256, 'gmssl.sm4'
? x gmssl.sm4
Output filename? gm.pyc
然后提取出来的代码是如下,这里这一部分是对key与37做了xor来加的密。
key = bytes_to_list(key)
key = (lambda .0: [k ^ 37 for k in .0])(key)
但是要注意的是,在Python中,使用点(.
)作为lambda表达式中的参数是无效的语法。
所以要写成
key = [ord(char) ^ 37 for char in original_key]
最终我们的解密脚本如下:
from gmssl import sm4
import base64
def unpad_pkcs7(padded_data):
'''PKCS#7去填充'''
padding_len = padded_data[-1]
return padded_data[:-padding_len]
def decryptSM4(key, encrypted_data):
gmsm4 = sm4.CryptSM4()
# 将列表转换为字节数组,然后进行编码
gmsm4.set_key(bytes(key), sm4.SM4_DECRYPT)
encrypted_data = base64.b64decode(encrypted_data)
decrypted_data = gmsm4.crypt_ecb(encrypted_data)
return unpad_pkcs7(decrypted_data).decode()
if __name__ == '__main__':
# 提供加密后的结果
encrypted_data = b'JmjJEAJGMT6F9bmC+Vyxy8Z1lpfaJzdEX6BGG/qgqUjUpQaYSON1CnZyX9YXTEClSRYm7PFZtGxmJw6LPuw1ww=='
# 提供用于解密的原始密钥
original_key = 'BeginCTFBeginCTF'
# 对密钥进行异或操作
key = [ord(char) ^ 37 for char in original_key]
# 解密数据
decrypted_data = decryptSM4(key, encrypted_data)
print(decrypted_data)
#得flag{Pay_M0re_@ttention_to_th3_key!!}
Begin-stick game
JavaScript 混淆,运用在线工具解决,然后修改score的值即可。
https://barrazacarlos.com/web-tools/zh/javascript-deobfuscator
SWPUCTF 2021 新生赛-简简单单的逻辑
题目原件就是py文件:
flag = 'xxxxxxxxxxxxxxxxxx'
list = [47, 138, 127, 57, 117, 188, 51, 143, 17, 84, 42, 135, 76, 105, 28, 169, 25]
result = ''
for i in range(len(list)):
key = (list[i]>>4)+((list[i] & 0xf)<<4)
result += str(hex(ord(flag[i])^key))[2:].zfill(2)
print(result)
# result=bcfba4d0038d48bd4b00f82796d393dfec
就是简单的分析逻辑的题目,
需要注意的就是[2:].zfill(2)
这个是用来搞定16进制数据的,就是去掉16进制前面的0x
,如果数据只有一位数就在前面补全(补0)。(附:列如字符串是a = “123456”就会是”3456“,如果是12或者3就是00,如果是123那就是03)但是实际对于我们编写解题程序没有影响。
写的解题py如下:
flag = ''
result="bcfba4d0038d48bd4b00f82796d393dfec"
list = [47, 138, 127, 57, 117, 188, 51, 143, 17, 84, 42, 135, 76, 105, 28, 169, 25]
for i in range(len(list)):
key = (list[i]>>4)+((list[i] & 0xf)<<4)
flag += chr(int(result[2 * i:2 * i + 2], 16) ^ key)
print (flag)
(list[i]>>4)+((list[i] & 0xf)<<4)
是如何做到将每个字节的高4位和低4位进行交换的: