Created
November 3, 2016 16:15
-
-
Save Graph-X/b578cd5c1fe737b2b6b6b09848fdaa8f to your computer and use it in GitHub Desktop.
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
#!/usr/bin/env python | |
import binascii | |
from struct import * | |
import os, sys | |
#import ctypes | |
import zlib | |
import struct | |
import array | |
import argparse | |
################################################################# | |
# | |
# unpacker parses out the binary and | |
# returns a list of the parts. The | |
# binary format is as follows: | |
# HEADER = 24 bytes | |
# start end #bytes field | |
# 0x0000 - 0x0003 (4 bytes) Magic number | |
# 0x0004 - 0x0005 (2 bytes) Major version | |
# 0x0006 - 0x0007 (2 bytes) Minor version | |
# 0x0008 - 0x000B (4 bytes) Compressed legth as litle endian | |
# 0x000c - 0x000f (4 bytes) CRC value of compressed data | |
# 0x0010 - 0x0013 (4 bytes) Uncompressed length | |
# /HEADER | |
# 0x0014 - EOF Zlib config data | |
################################################################ | |
def config_unpacker(confile, config): | |
fobject = open(confile, 'rb') | |
mn = ''.join(struct.unpack('4s', fobject.read(4))) | |
major = ''.join(struct.unpack('2s', fobject.read(2))) | |
minor = ''.join(struct.unpack('2s', fobject.read(2))) | |
clen = (struct.unpack('<i', fobject.read(4)))[0] | |
crc = (struct.unpack('<i', fobject.read(4)))[0] | |
ulen = (struct.unpack('<i', fobject.read(4)))[0] | |
#rest of the file should be the config | |
confD = (struct.unpack('@%ds' % clen, fobject.read(clen)))[0] | |
#ZOMG IT'S DATA VALIDATION!!!!!!!! | |
if len(confD) == clen: | |
if zlib.crc32(confD) == crc: | |
unconfD = zlib.decompress(confD) | |
if len(unconfD) == ulen: | |
###################################################################################### | |
# FUCK YEA!!! IT ALL CHECKS OUT! | |
# I'm way too excited over the fact you've made it this far | |
# You should be too, I never thought this script would work in a million years | |
###################################################################################### | |
parts = [unconfD, 0] | |
with open(config, 'w') as f: | |
f.write(parts) | |
return parts | |
else: | |
print('[!] header ulen does not match uncompressed data length. ulen = %d and size = %d You done fucked up now boy!'% (ulen, len(unconfD))) | |
else: | |
print('[!] CRC check failed! Upgrayedd will now find you! Fix your old and busted shit and come back to me. Values were header CRC: %d and latest CRC: %d'% (crc, zlib.crc32(unconfD))) | |
else: | |
print('[!] Compressed values from header and data do not match. You really screwed the pooch on this one, diddn\'t ya.\nvalues are: header compressed size %d and %d for calculated length'% (clen, len(confD))) | |
confD = fobject.read() | |
fobject.close() | |
parts = [mn,maj,min,ulen,crc,clen] | |
return parts | |
################################################ | |
# packer function take the config, builds the | |
# header and converts the reassembled file | |
# back to a binary config. | |
# Format: | |
# HEADER | |
# start end #bytes field | |
# 0x0000 - 0x0003 (4 bytes) Magic number | |
# 0x0004 - 0x0005 (2 bytes) Major version | |
# 0x0006 - 0x0007 (2 bytes) Minor version | |
# 0x0008 - 0x000B (4 bytes) Compressed legth as litle endian | |
# 0x000c - 0x000f (4 bytes) CRC value of compressed data | |
# 0x0010 - 0x0013 (4 bytes) Uncompressed length | |
# /HEADER | |
# 0x0014 - EOF Zlib config data | |
################################################### | |
def config_packer(outfile, config, magic_number, major, minor): | |
ulen = len(config) | |
print("[*] ulen is %d"% ulen) | |
compressed_config = zlib.compress(config) | |
clen = len(compressed_config) | |
print("[*] compressed length is %d"% clen) | |
crc = zlib.crc32(compressed_config) | |
print("[*] CRC is %d"% crc) | |
buf = struct.pack('!4s2i', ''.join(magic_number), major, minor) | |
buf += struct.pack('<3i', clen, crc, ulen) | |
if len(compressed_config) == clen: | |
buf += struct.pack('%ds' % (clen), compressed_config) | |
try: | |
with open(outfile, 'wb') as output: | |
output.write(buf) | |
output.close() | |
print("[+] buffer has been written to the file successfully") | |
return True | |
except Exception as e: | |
print("[!] couldn't write the config file. Got the following error: %s" % (str(e))) | |
return False | |
else: | |
print("[!] Compresed length does not match length of compressed data clen = %d len(compressed_data) = %d" % (clen, len(compressed_config))) | |
return False | |
def get_args(): | |
parser = argparse.ArgumentParser() | |
parser.add_argument('-p', '--pack', dest='pact', action='store_true', help="pack up a config") | |
parser.add_argument('-u', '--unpack',dest='unpact', action='store_true', help="unpack a config") | |
parser.add_argument('-b', '--binfile', dest='binfile', help="binary config file" ) | |
parser.add_argument('-x', '--xmlfile', dest='config', required=True, help="plain text xml config file") | |
args = parser.parse_args() | |
if len(sys.argv) == 1: | |
parser.print_help() | |
sys.exit(2) | |
else: | |
return args | |
def main(): | |
magic_number = ('L', 'M', 'M', 'N') | |
major = 0x0003 | |
minor = 0x0000 | |
args = get_args() | |
p = args.pact | |
u = args.unpact | |
config = args.config #plain text xml config | |
binfile = args.binfile #binary config | |
if p and u: | |
print("[-] You can't pack and unpack at the same time ya dolt. Go fix your shit and come back when your head's out of your ass") | |
sys.exit(2) | |
if not args.config or not args.binfile: | |
print("[-] Alright there snowflake, you need to specify an xml file and a binary file for me to work with here. Go to the end of the line and try again") | |
sys.exit(2) | |
if p: | |
with open(config, 'r') as con: | |
context = con.read() | |
result = config_packer(binfile, context, magic_number, major, minor) | |
con.close() | |
if result: | |
print("[+] New config file is packed and ready for upload: %s" % binfile) | |
sys.exit(0) | |
else: | |
print("[-] I'm pretty sure you fucked up, but the guy who wrote me didn't add in a lot of error checking. You might want to try this again.") | |
sys.exit(2) | |
if u: | |
result = config_unpacker(binfile,config) | |
if result: | |
print("[+] New config xml file is unpacked and read to hack: %s" % config) | |
sys.exit(0) | |
else: | |
print("[-] I'm not sure this worked out how we intended. You might want to double check that bin file") | |
sys.exit(2) | |
if __name__ == "__main__": | |
main() |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment