├── README.md └── lzma-unpacker.py /README.md: -------------------------------------------------------------------------------- 1 | #LZMA Unpacker 2 | 3 | Extract LZMA sections from cable modem firmware images 4 | 5 | For more information: http://w00tsec.blogspot.com/2013/11/unpacking-firmware-images-from-cable.html 6 | 7 | Tested with the following Cable Modems: 8 | - Cisco DPC3925, DPC2434 9 | - Motorola SB5100, SB5101, SVG6582, SVG1202 10 | - Thomson ACG905, DCM425, DHG534, DHG544, DWG850, DWG874 11 | - Webstar DPC2203 12 | 13 | #Prerequisites: 14 | - [Binwalk](https://code.google.com/p/binwalk/) 15 | 16 | #Screenshots 17 | 18 | ![Screenshot](http://4.bp.blogspot.com/-nXdE3Riusdw/Un5ICQNw93I/AAAAAAAAAIU/BZYzsoT3Les/s640/screenshot.png) 19 | 20 | #Usage 21 | python lzma-unpacker.py firmware_image.bin 22 | -------------------------------------------------------------------------------- /lzma-unpacker.py: -------------------------------------------------------------------------------- 1 | #!/usr/bin/python 2 | 3 | import os, sys 4 | from binwalk import Binwalk 5 | 6 | def lzma_callback(offset, results): 7 | for result in results: 8 | if result['description'].startswith('LZMA compressed data, properties: 0x5D'): 9 | with open(sys.argv[1]) as f: 10 | f.seek(result['offset']) 11 | lzma_header = f.read(5) 12 | uncompressed_size = '\x00\x00\x00\x10\x00\x00\x00\x00' 13 | data = f.read() 14 | output = open(sys.argv[1]+'.lzma', 'w') 15 | output.write(lzma_header+uncompressed_size+data) 16 | f.close() 17 | 18 | if __name__ == '__main__': 19 | nargs = len(sys.argv) 20 | 21 | if nargs != 2: 22 | print '\ 23 | \nLZMA Unpacker: Extract LZMA sections from firmware images\n\ 24 | \nTested with the following Cable Modems:\n\ 25 | - Cisco DPC3925, DPC2434\n\ 26 | - Motorola SB5100, SB5101, SVG6582, SVG1202\n\ 27 | - Thomson ACG905, DCM425, DHG534, DHG544, DWG850, DWG874\n\ 28 | - Webstar DPC2203\n\ 29 | \nBernardo Rodrigues, http://w00tsec.blogspot.com\n\ 30 | \nUsage: %s firmware_image.bin' % os.path.basename(sys.argv[0])+'\n' 31 | 32 | else: 33 | with Binwalk() as bw: 34 | try: 35 | with open(sys.argv[1], 'rb'): 36 | bw.display.header() 37 | bw.scan(sys.argv[1], callback=lzma_callback, show_invalid_results=True) 38 | try: 39 | with open(sys.argv[1]+'.lzma', 'rb'): 40 | bw.extractor.add_rule('lzma:7z:7zr e -y %e') 41 | bw.scan(sys.argv[1]+'.lzma', callback=bw.display.results) 42 | except Exception: 43 | print 'LZMA 0x5D signature not found' 44 | exit 45 | except IOError: 46 | print 'File not found: '+sys.argv[1] 47 | 48 | --------------------------------------------------------------------------------