Created
October 14, 2023 09:24
-
-
Save kobuki/a8d25bd0e0dd4d150e2d233d53b3b2c4 to your computer and use it in GitHub Desktop.
MikroTik WinBox WBX dump script
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/python | |
| # wbx.py - dump MikroTik winbox addresses.wbx file format | |
| # Based on: https://github.com/simeonmiteff/junkbox/blob/master/wbx.py | |
| # Fixed & amended for Python 3 and added JSON output. | |
| import sys | |
| import json | |
| def munge_pair(pair): | |
| """ Convert integer values to integers """ | |
| name, value, _offset = pair | |
| if name in ['secure-mode', 'keep-pwd']: | |
| value = ord(value) | |
| return (name, value, _offset) | |
| def get_pair(_offset, _data): | |
| """ Extract a name/value pair from the data at offset """ | |
| if _data[_offset] == 0: | |
| # End of record | |
| # Return (None, None, offset of next record) | |
| return (None, None, _offset+2) | |
| rlen = _data[_offset] - 1 # Record length | |
| nlen = _data[_offset+2] # Name length | |
| vlen = rlen-nlen # Value length | |
| _offset = _offset+3 # Skip to the name | |
| name = str(_data[_offset:_offset+nlen], 'utf-8') | |
| _offset = _offset+nlen # Skip to the value | |
| value = str(_data[_offset:_offset+vlen], 'utf-8') | |
| # Return (name, value, offset of next pair) | |
| return (name, value, _offset + vlen) | |
| if __name__ == "__main__": | |
| # Check arguments | |
| if len(sys.argv) < 2: | |
| sys.stderr.write(f"Usage: {sys.argv[0]} filename.wbx [-j]\n") | |
| sys.exit(1) | |
| # Open file | |
| try: | |
| wbxfile = open(sys.argv[1], mode="rb") | |
| except IOError as e: | |
| sys.stderr.write(f"Failed to open file '{sys.argv[1]}': {str(e)}\n") | |
| sys.exit(1) | |
| jsonDump = False | |
| if len(sys.argv) > 2 and sys.argv[2] == '-j': | |
| jsonDump = True | |
| out = [] | |
| data = wbxfile.read() # Slurp the wbx file into a string | |
| headings = ['group', 'host', 'keep-pwd', 'login', 'note', 'pwd', 'secure-mode', 'type'] | |
| offset = 4 # Skip the 4-byte file header | |
| if not jsonDump: | |
| for head in headings: # Print headings | |
| sys.stdout.write(head.ljust(40)) | |
| print() | |
| for head in headings: # Underline them | |
| sys.stdout.write(('-'*len(head)).ljust(40)) | |
| print() | |
| # Dump data | |
| try: | |
| entry = {} | |
| while True: | |
| n, v, offset = munge_pair(get_pair(offset, data)) | |
| if not n: | |
| if jsonDump: | |
| out.append(entry) | |
| entry = {} | |
| else: | |
| print() | |
| continue | |
| if jsonDump: | |
| entry[n] = v | |
| else: | |
| sys.stdout.write(str(v).ljust(40)) | |
| except IndexError: | |
| pass | |
| if jsonDump: | |
| print(json.dumps(out, indent=4, ensure_ascii=False)) |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment