| skipped 12 lines |
13 | 13 | | import StringIO |
14 | 14 | | import gzip |
15 | 15 | | import array |
| 16 | + | import platform |
16 | 17 | | |
17 | 18 | | # Patch dir this file was loaded from into the path |
18 | 19 | | # (Burp doesn't do it automatically) |
| skipped 16 lines |
35 | 36 | | from ui import ParameterProcessingRulesTable |
36 | 37 | | |
37 | 38 | | |
38 | | - | CONTENT_PROTOBUF = ('application/grpc-web+proto') |
| 39 | + | CONTENT_PROTOBUF = ['application/x-protobuf', 'application/x-protobuffer', 'application/x-protobuffer; charset=utf-8', 'application/octet-stream', 'application/grpc-web+proto'] |
39 | 40 | | |
40 | 41 | | PROTO_FILENAME_EXTENSION_FILTER = FileNameExtensionFilter("*.proto, *.py", |
41 | 42 | | ["proto", "py"]) |
| skipped 1 lines |
43 | 44 | | |
44 | 45 | | def detectProtocBinaryLocation(): |
45 | 46 | | system = System.getProperty('os.name') |
| 47 | + | arch = platform.architecture()[0] |
46 | 48 | | |
47 | | - | if system == "Linux": |
48 | | - | os.chmod("./protoc-linux", 0755) |
49 | | - | return os.path.join(os.getcwd(), "protoc-linux") |
50 | | - | elif system.startswith("Mac "): |
51 | | - | os.chmod("./protoc-mac", 0755) |
52 | | - | return os.path.join(os.getcwd(), "protoc-mac") |
53 | | - | elif system.startswith("Windows "): |
54 | | - | return os.path.join(os.getcwd(), "protoc-windows.exe") |
| 49 | + | if arch == "32bit": |
| 50 | + | if system == "Linux": |
| 51 | + | os.chmod("./protoc-linux-32", 0755) |
| 52 | + | return os.path.join(os.getcwd(), "protoc-linux-32") |
| 53 | + | elif system.startswith("Mac "): |
| 54 | + | os.chmod("./protoc-mac-32", 0755) |
| 55 | + | return os.path.join(os.getcwd(), "protoc-mac-32") |
| 56 | + | elif system.startswith("Windows "): |
| 57 | + | return os.path.join(os.getcwd(), "protoc-windows-32.exe") |
| 58 | + | else: |
| 59 | + | raise RuntimeError("Unrecognized operating system: " + system) |
| 60 | + | elif arch == "64bit": |
| 61 | + | if system == "Linux": |
| 62 | + | os.chmod("./protoc-linux-64", 0755) |
| 63 | + | return os.path.join(os.getcwd(), "protoc-linux-64") |
| 64 | + | elif system.startswith("Mac "): |
| 65 | + | os.chmod("./protoc-mac-64", 0755) |
| 66 | + | return os.path.join(os.getcwd(), "protoc-mac-64") |
| 67 | + | elif system.startswith("Windows "): |
| 68 | + | return os.path.join(os.getcwd(), "protoc-windows-64.exe") |
| 69 | + | else: |
| 70 | + | raise RuntimeError("Unrecognized operating system: " + system) |
55 | 71 | | else: |
56 | | - | raise RuntimeError("Unrecognized operating system: " + system) |
| 72 | + | raise RuntimeError("Unrecognized operating system architecture: " + arch) |
| 73 | + | |
57 | 74 | | |
58 | 75 | | PROTOC_BINARY_LOCATION = detectProtocBinaryLocation() |
59 | 76 | | |
| skipped 19 lines |
79 | 96 | | |
80 | 97 | | |
81 | 98 | | class BurpExtender(IBurpExtender, IMessageEditorTabFactory, ITab, IExtensionStateListener): |
82 | | - | EXTENSION_NAME = "grpc-web-proto Decoder Tab" |
| 99 | + | EXTENSION_NAME = "Protobuf Decoder" |
83 | 100 | | |
84 | 101 | | def __init__(self): |
85 | 102 | | self.descriptors = OrderedDict() |
| skipped 76 lines |
162 | 179 | | |
163 | 180 | | |
164 | 181 | | class ProtobufEditorTab(IMessageEditorTab): |
165 | | - | TAB_CAPTION = "grpc-web-proto editor tab" |
| 182 | + | TAB_CAPTION = "Protobuf Decoder" |
166 | 183 | | |
167 | 184 | | def __init__(self, extender, controller, editable): |
168 | 185 | | self.extender = extender |
| skipped 99 lines |
268 | 285 | | #set message |
269 | 286 | | rawBytes = (content[info.getBodyOffset():]) |
270 | 287 | | global oldPadding |
| 288 | + | global hasPadding |
| 289 | + | hasPadding = False |
| 290 | + | |
271 | 291 | | oldPadding= rawBytes[0:4] |
272 | 292 | | if rawBytes[0] == 0 and rawBytes[1] == 0 and rawBytes[2] == 0 and rawBytes[3] == 0: |
273 | 293 | | rawBytes = rawBytes[5:rawBytes[4]+5] |
| 294 | + | hasPadding = True |
274 | 295 | | body = rawBytes.tostring() |
275 | 296 | | |
276 | 297 | | # Loop through all proto descriptors loaded |
| skipped 69 lines |
346 | 367 | | headers = info.getHeaders() |
347 | 368 | | serialized = message.SerializeToString() |
348 | 369 | | |
| 370 | + | if hasPadding: |
| 371 | + | oldPadding.append(len(serialized)) |
| 372 | + | serialized = oldPadding.tostring() + serialized |
349 | 373 | | |
350 | | - | oldPadding.append(len(serialized)) |
351 | | - | serialized = oldPadding.tostring() + serialized |
352 | 374 | | if parameter is not None: |
353 | 375 | | rules = self.extender.table.getParameterRules().get(parameter.getName(), {}) |
354 | 376 | | |
| skipped 159 lines |
514 | 536 | | # cut 5 bytes for grpc web |
515 | 537 | | rawBytes = (content[info.getBodyOffset():]) |
516 | 538 | | global oldPadding |
| 539 | + | global hasPadding |
| 540 | + | hasPadding = False |
| 541 | + | |
517 | 542 | | oldPadding= rawBytes[0:4] |
518 | 543 | | if rawBytes[0] == 0 and rawBytes[1] == 0 and rawBytes[2] == 0 and rawBytes[3] == 0: |
519 | 544 | | rawBytes = rawBytes[5:] |
| 545 | + | hasPadding = True |
| 546 | + | |
520 | 547 | | body = rawBytes.tostring() |
521 | 548 | | |
522 | 549 | | |
| skipped 53 lines |