def encode(openPath, writePath, data, mapSeed, password=""): """encode a text file with data using homoglyphs Args: openPath (string): path to the original text file to open writePath (string): path to write the stego-text file data (string): data to encode mapSeed (string): seed to generate the lsb map password (str, optional): password to encrypt the data with. Defaults to "". """ with open(openPath, encoding="utf-8") as openData: fileData = openData.read() position = 0 output = [] data = otp(toBin(data), password) + b"\x00" encodeMap = getMap(fileData, mapSeed) systemRandom = SystemRandom() for char in data: shift = 0 while shift < 8: if encodeMap[position] > 0: result, shift = encodeGlyph(fileData, position, char, shift) else: result, _shift = encodeGlyph(fileData, position, systemRandom.randint(0, 1) << shift, shift) output.append(result) position += 1 output.append(fileData[position:]) with open(writePath, "w", encoding="utf-8") as writeData: writeData.write("".join(output))
def encodeComment(openPath, writePath, data): """encode an microsoft office file with data by inserting into xml comments Args: openPath (string): path to the original office document to open writePath (string): path to write the stego-office document data (string|bytes|<file>): data to encode """ # iterate xml files and inject data in chunks copyfile(openPath, writePath) with MutableZipFile(writePath, "a", compression=ZIP_DEFLATED) as zipFile: files = [] for file in zipFile.namelist(): if file.endswith((".xml")): files.append(file) files.sort() # Split data into chunks chunkLen = ceil(len(data) / len(files)) data = toBin(data) for iteration, file in enumerate(files): with zipFile.open(file, "r") as xmlFile: lines = [line.strip() for line in xmlFile.readlines()] lines.insert( 1, b"<!--" + data[chunkLen * (iteration):chunkLen * (iteration + 1)] + b"-->") zipFile.writestr(file, b"\n".join(lines))
def encode(openPath, writePath, data, mapSeed, password="", safe=True): """encode a text file with data using zero width chars Args: openPath (string): path to the original text file to open writePath (string): path to write the stego-text file data (string|bytes|<file>): data to encode mapSeed (string): seed to generate the lsb map password (str, optional): password to encrypt the data with. Defaults to "". safe (boolean, optional): use a reduced set of chars to show in fewer editors. Defaults to True. """ with open(openPath, "rb") as openData: fileData = openData.read() position = 0 pointer = 0 zwcMap = getMap(fileData, mapSeed) encodeData = otp(toBin(data), password) + b"\x00" while pointer < len(encodeData): if zwcMap[position] > 0: position, fileData = encodeCharZero(fileData, position, encodeData[pointer], safe) pointer += 1 else: position += getUtf8Size(fileData, position)[0] # increment by char size with open(writePath, "wb") as writeData: writeData.write(fileData)
def encode(openPath, writePath, appendData, password=""): """encode a file with data by appending binary after the end of the file Args: openPath (string): path to the original file to open writePath (string): path to write the stego-file appendData (string|bytes|<file>): data to encode password (str, optional): password to encrypt the data with. Defaults to "". """ data, fileExt = openFile(openPath) imageWriteData = data[:data.find(endKeys[fileExt]) + len(endKeys[fileExt])] writeFile(writePath, imageWriteData + otp(toBin(appendData), password))
def simpleEncode(openPath, writePath, data, safe=True): """encode a text file with data using zero width chars Args: openPath (string): path to the original text file to open writePath (string): path to write the stego-text file data (string|bytes|<file>): data to encode safe (boolean, optional): use a reduced set of chars to show in fewer editors. Defaults to True. """ with open(openPath, "rb") as openData: fileData = openData.read() position = 0 for char in toBin(data) + b"\x00": position, fileData = encodeCharZero(fileData, position, char, safe) with open(writePath, "wb") as writeData: writeData.write(fileData)
def encodeFile(openPath, writePath, file, fileName="application.xml", password=""): """ encode data as a file """ # Add one of the following: # <Override PartName="/docProps/<file>" ContentType="application/octet-stream"/> # <Override PartName="/docProps/application.xml" # ContentType="application/vnd.openxmlformats-officedocument.extended-properties+xml"/> copyfile(openPath, writePath) with MutableZipFile(writePath, "a", compression=ZIP_DEFLATED) as zipFile: zipFile.writestr("docProps/" + fileName, otp(toBin(file), password)) with zipFile.open("[Content_Types].xml", "r") as xmlFile: lines = [line.strip() for line in xmlFile.readlines()] lines[1] = lines[1].replace( b"</Types>", b"<Override PartName=\"/docProps/" + fileName.encode("utf-8") + b"\" ContentType=\"application/" + (b"vnd.openxmlformats-officedocument.extended-properties+xml" if fileName == "application.xml" else b"octet-stream") + b"\"/></Types>") zipFile.writestr("[Content_Types].xml", b"\n".join(lines))
def simpleEncode(openPath, writePath, data): """encode a text file with data using homoglyphs Args: openPath (string): path to the original text file to open writePath (string): path to write the stego-text file data (string|bytes|<file>): data to encode """ with open(openPath, encoding="utf-8") as openData: fileData = openData.read() position = 0 output = [] data = toBin(data) for char in data + b"\x00": shift = 0 while shift < 8: result, shift = encodeGlyph(fileData, position, char, shift) output.append(result) position += 1 output.append(fileData[position:]) with open(writePath, "w", encoding="utf-8") as writeData: writeData.write("".join(output))
def encodeFile(openPath, writePath, file, fileName="application.xml", password=""): """ encode data as a file """ # Add one of the following: <manifest:manifest></manifest:manifest> # <manifest:file-entry manifest:full-path="<file>" manifest:media-type="application/octet-stream"/> # <manifest:file-entry manifest:full-path="/application.xml" # manifest:media-type="text/xml"/> copyfile(openPath, writePath) with MutableZipFile(writePath, "a", compression=ZIP_DEFLATED) as zipFile: zipFile.writestr(fileName, otp(toBin(file), password)) with zipFile.open("META-INF/manifest.xml", "r") as xmlFile: lines = [line.strip() for line in xmlFile.readlines()] lines[1] = lines[1].replace( b"</manifest:manifest>", b"<manifest:file-entry manifest:full-path=\"" + fileName.encode("utf-8") + b"\" manifest:media-type=\"" + (b"text/xml" if fileName == "application.xml" else b"application/octet-stream") + b"\"/></manifest:manifest>") zipFile.writestr("META-INF/manifest.xml", b"\n".join(lines))
def __init__(self, array, pointer=0, data=None): self.array = array self.arrayLen = len(array) self.pointer = pointer self.data = toBin(data)