encrypt
import sys
import json
import hashlib
class Crypto:
def __init__(self, key):
if not isinstance(key, bytes):
raise TypeError('key must be of type bytes!')
self.key = key
self._buf = bytes()
self._out = open("/dev/stdout", "wb")
def _extend_buf(self):
self._buf += self.key
def get_bytes(self, nbytes):
while len(self._buf) < nbytes:
self._extend_buf()
ret, self._buf = self._buf[:nbytes], self._buf[nbytes:]
return ret
def encrypt(self, buf):
if not isinstance(buf, bytes):
raise TypeError('buf must be of type bytes!')
stream = self.get_bytes(len(buf))
return bytes(a ^ b for a, b in zip(buf, stream))
def set_outfile(self, fname):
self._out = open(fname, "wb")
def encrypt_file(self, fname):
buf = open(fname, "rb").read()
self._out.write(self.encrypt(buf))
class JSONCrypto(Crypto):#Crypto的子类.
def encrypt_file(self, fname):
buf = open(fname, "r").read().strip()
h = hashlib.sha256(buf.encode('utf-8')).hexdigest()
data = {
"filename": fname,
"hash": h,
"plaintext": buf,
}
outbuf = json.dumps(data, sort_keys=True, indent=4)
self._out.write(self.encrypt(outbuf.encode("utf-8")))
def main(argv):
if len(argv) not in (3, 4):
print("%s <key> <infile> [outfile]" % sys.argv[0])
return
argv.pop(0)
key = argv.pop(0)
inf = argv.pop(0)
crypter = JSONCrypto(key.encode("utf-8"))
if sys.argv:
crypter.set_outfile(argv.pop(0))
crypter.encrypt_file(inf)
if __name__ == '__main__':
main(sys.argv)
decrypt
通过代码审计,可以大致了解加密过程为将数据格式化为:
这个形式后,再与多次重复的key(为了长度和data一样)进行异或来得到密文.我们猜测fname的名字应该为flag.txt(因为密文为flag.txt.enc),这样,如果key不够长的话,我们很容易就可以求出key了.
import json
data = {
"filename": 'flag.txt',
"hash": 'h',
}
outbuf = json.dumps(data, sort_keys=True, indent=4)
cipher_pre=open('flag.txt.enc','rb').read()
for i in range(43):
print(chr(cipher_pre[i]^ord(outbuf[i])))
key='n0t4=l4g'
for i in range(8):
key+=key
#使key足够长.
print(key)
flag=''
for i in range(len(cipher_pre)):
flag+=chr(ord(key[i])^cipher_pre[i])
print(flag)
# {
# "filename": "flag.txt",
# "hash": "2f98b8afa014bf955533a3e72cee0417413ff744e25f2b5b5838f5741cd69547",
# "plaintext": "CTF{plz_dont_r0ll_ur_own_crypto}"
# }