From 854b8d67b715eb44b2427771f49208811b3d7014 Mon Sep 17 00:00:00 2001 From: Robin David Date: Sat, 11 Nov 2023 20:34:38 +0100 Subject: [PATCH] add tutorial firmware diffing --- _static/tutorials/RAX30.jpeg | Bin 0 -> 21543 bytes tutorials/04c_firmware_diffing.ipynb | 519 +++++++++++++++++++++++++++ tutorials/tutorials.rst | 4 +- 3 files changed, 521 insertions(+), 2 deletions(-) create mode 100644 _static/tutorials/RAX30.jpeg create mode 100644 tutorials/04c_firmware_diffing.ipynb diff --git a/_static/tutorials/RAX30.jpeg b/_static/tutorials/RAX30.jpeg new file mode 100644 index 0000000000000000000000000000000000000000..76bb580f7c9c6ed88edc0adbd46b8544dbe599d7 GIT binary patch literal 21543 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\n", + " \"symbols\n", + "" + ] + }, + { + "cell_type": "markdown", + "id": "a8039e09-da0f-486e-983f-d4b7360d2e8b", + "metadata": {}, + "source": [ + "For this tutorial we are going to work on the Netgear RAX30 Wireless router, that was part of the targets for [Pwn2Own Toronto 2022](https://www.zerodayinitiative.com/blog/2022/8/29/announcing-pwn2own-toronto-2022-and-introducing-the-soho-smashup). A day before the submission deadline, Netgear\n", + "released a firmware update that was also patching some vulnerabilities (which led multiple Pwn2Own competitors to withdraw theirs submission). The two versions are:\n" + ] + }, + { + "cell_type": "raw", + "id": "2c0d6a18-0fee-43a4-8a89-0509b960bdaf", + "metadata": {}, + "source": [ + "
\n", + "
\n", + " \n", + "
1.0.7.78\n", + "
\n", + "
\n", + "
\n", + " \n", + "
1.0.9.92\n", + "
\n", + "
\n", + "
\n", + "
" + ] + }, + { + "cell_type": "markdown", + "id": "ae171c81-5f4b-4d99-a078-7a3dd2e85f6c", + "metadata": {}, + "source": [ + "The goal of this tutorial is to show how performing a full-filesystem diff and to navigate the results programatically." + ] + }, + { + "attachments": {}, + "cell_type": "markdown", + "id": "69aa55d0-e03b-4466-b3b3-3322c0384e2c", + "metadata": {}, + "source": [ + "## I. Unpacking firmwares\n", + "\n", + "To extract the firmwares one can use [Unblob](https://unblob.org) which is now undeniably\n", + "the best firmware extraction tool to date. We can extract the firmware with:\n", + "\n", + "```bash\n", + "docker run \\\n", + " --rm \\\n", + " --pull always \\\n", + " -v $PWD/extract/RAX30-V1.0.7.78_1.img_extract:/data/output \\\n", + " -v $PWD:/data/input \\\n", + " ghcr.io/onekey-sec/unblob:latest /data/input/RAX30-V1.0.7.78_1.img\n", + "```\n", + "\n", + "*(Considering the firmware is in your current directory)*" + ] + }, + { + "cell_type": "markdown", + "id": "73243da5-ae38-40d1-99bc-d03567f01d1d", + "metadata": {}, + "source": [ + "**Exercise**: Unpack both firmwares" + ] + }, + { + "attachments": {}, + "cell_type": "markdown", + "id": "5ef720c2-5c99-458d-a0c0-b1b32d8c6ebf", + "metadata": {}, + "source": [ + "## II. Exporting files\n", + "\n", + "Before diffing executables between the two firmwares, we have to call BinExport on all of them.\n", + "For that we can use the program ``binexporter`` that can iterate a whole tree of files and to\n", + "export all files encountered.\n", + "\n", + "```bash\n", + " binexporter -t 10 extract/RAX30-V1.0.7.78_1.img_extract\n", + "```\n", + "\n", + "The option ``-t`` launch the export with 10 processes. As exporting implies disassembling all binaries it can take a while to perform (~1h for this firmware)." + ] + }, + { + "cell_type": "markdown", + "id": "16727be6-59cf-4642-8cdc-90046a45310a", + "metadata": {}, + "source": [ + "To continue the tutorial here are the binexports files for both firmwares." + ] + }, + { + "cell_type": "raw", + "id": "e1c3bf1a-2848-417b-bd38-8b1b08bf8e82", + "metadata": {}, + "source": [ + "\n", + "
" + ] + }, + { + "attachments": {}, + "cell_type": "markdown", + "id": "d41498dc-c51f-4be8-a960-5d8ba14aff70", + "metadata": {}, + "source": [ + "## III. Performing the diff\n", + "\n", + "Now that all executable files are exported in a single directory for each firmwares\n", + "we can perfom the diff of each BinExport files based on theirs name. *(For simplicity\n", + "we assume there are now duplicates. Also symlinks also led to duplicating binexport files)*.\n", + "\n", + "**Exercise**: Write a script to diff all binexports files." + ] + }, + { + "cell_type": "raw", + "id": "e2614e46-224e-4d88-b770-5d11d5eeb1d9", + "metadata": {}, + "source": [ + "" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "id": "f178386d-82f4-4770-b70a-9467d80c8b27", + "metadata": {}, + "outputs": [], + "source": [ + "from pathlib import Path\n", + "from bindiff import BinDiff, BindiffFile\n", + "\n", + "binexports1 = Path(\"binexports/RAX30-V1.0.7.78_1.img_extract\")\n", + "binexports2 = Path(\"binexports/RAX30-V1.0.9.90_3.img_extract\")\n", + "\n", + "diff_dir = Path(\"diffs\") # create output dir\n", + "diff_dir.mkdir()\n", + "\n", + "for file1 in binexports1.iterdir():\n", + " file2 = binexports2 / file1.name\n", + " if file2.exists():\n", + " diff_file = diff_dir / f\"{file1.with_suffix('').name}_vs_{file2.with_suffix('').name}.BinDiff\"\n", + " if not diff_file.exists():\n", + " print(f\"diff {file1} | {file2}: \", end=\"\")\n", + " print(BinDiff.raw_diffing(file1, file2, diff_file)) # Perform the diff" + ] + }, + { + "attachments": {}, + "cell_type": "markdown", + "id": "bfee8305-38e3-4367-a805-2316284b2d42", + "metadata": {}, + "source": [ + "## IV. Analyzing diffs\n", + "\n", + "Now that all diff files are created we can open them to analyze changes.\n", + "\n", + "**Exercise**: Write a script that take the 15 most different binaries (similarity the lowest), and which shows the 10 most different functions (dissimilar ones)." + ] + }, + { + "cell_type": "raw", + "id": "98a38e1f-f747-4b1a-a0b1-2308e7dd3987", + "metadata": {}, + "source": [ + "" + ] + }, + { + "cell_type": "code", + "execution_count": 8, + "id": "4bb33a8b-e255-470b-8888-9670e803b6e1", + "metadata": {}, + "outputs": [ + { + "data": { + "application/vnd.jupyter.widget-view+json": { + "model_id": "1656800305ae4025bc1f20a562b9149c", + "version_major": 2, + "version_minor": 0 + }, + "text/plain": [ + "IntProgress(value=0, description='Load diffs', max=965)" + ] + }, + "metadata": {}, + "output_type": "display_data" + }, + { + "name": "stdout", + "output_type": "stream", + "text": [ + "xCloud_Debug_log.zip: 49% [matched:140][unmatched:28-28]:\n", + " - sub_000115D8 (10%)\n", + " - sub_00013DBC (59%)\n", + " - _ITM_registerTMCloneTable (100%)\n", + " - __imp___gmon_start__ (100%)\n", + " - _ITM_deregisterTMCloneTable (100%)\n", + " - __imp_fwrite (100%)\n", + " - __imp_json_object_object_add (100%)\n", + " - __imp_strstr (100%)\n", + " - __imp_snprintf (100%)\n", + " - __imp_cmsLog_cleanup (100%)\n", + "debug.cgi: 49% [matched:140][unmatched:28-28]:\n", + " - sub_000115D8 (10%)\n", + " - sub_00013DBC (59%)\n", + " - _ITM_registerTMCloneTable (100%)\n", + " - __imp___gmon_start__ (100%)\n", + " - _ITM_deregisterTMCloneTable (100%)\n", + " - __imp_fwrite (100%)\n", + " - __imp_json_object_object_add (100%)\n", + " - __imp_strstr (100%)\n", + " - __imp_snprintf (100%)\n", + " - __imp_cmsLog_cleanup (100%)\n", + "libmdm_db.so: 51% [matched:258][unmatched:418-418]:\n", + " - oalMdm_isParam64 (63%)\n", + " - strstr (66%)\n", + " - mdm_deleteObjectInstance (92%)\n", + " - j_mdm_getObject (99%)\n", + " - mdm_getNextObjPathDesc (99%)\n", + " - sub_00005F68 (99%)\n", + " - sub_0000B864 (99%)\n", + " - mdm_moveInstanceUsingNewOrderValue (99%)\n", + " - j_mdm_getOrderValue (99%)\n", + " - mdm_setOrderValue (99%)\n", + "wbd_master: 54% [matched:582][unmatched:13-13]:\n", + " - sub_00024890 (1%)\n", + " - sub_0002E244 (1%)\n", + " - sub_0001F640 (1%)\n", + " - sub_0002FA78 (2%)\n", + " - sub_0002F974 (3%)\n", + " - sub_0002F188 (3%)\n", + " - sub_0002ABA4 (3%)\n", + " - sub_000206D4 (5%)\n", + " - sub_00029A30 (6%)\n", + " - sub_0002A318 (6%)\n", + "wbd_slave: 55% [matched:867][unmatched:12-12]:\n", + " - sub_00040044 (0%)\n", + " - sub_00040520 (1%)\n", + " - sub_00040F88 (1%)\n", + " - sub_00041DC8 (1%)\n", + " - sub_00031930 (1%)\n", + " - sub_000277E4 (1%)\n", + " - sub_0001EEF4 (1%)\n", + " - sub_0001B518 (1%)\n", + " - sub_000277A0 (1%)\n", + " - sub_00040934 (1%)\n", + "xt_comment.ko: 63% [matched:3][unmatched:0-0]:\n", + " - comment_mt_exit (100%)\n", + " - init_module (100%)\n", + " - comment_mt (100%)\n", + "ssd: 63% [matched:88][unmatched:1-1]:\n", + " - sub_000117C4 (54%)\n", + " - sub_00010B94 (61%)\n", + " - sprintf (66%)\n", + " - nvram_set (66%)\n", + " - strcmp (66%)\n", + " - setsockopt (66%)\n", + " - strcspn (66%)\n", + " - strspn (66%)\n", + " - nvifname_to_osifname (66%)\n", + " - malloc (66%)\n", + "xt_SKIPLOG.ko: 64% [matched:4][unmatched:0-0]:\n", + " - blog_skip (100%)\n", + " - skiplog_tg_exit (100%)\n", + " - skiplog_tg_init (100%)\n", + " - skiplog_tg (100%)\n", + "wb_cli: 73% [matched:70][unmatched:0-0]:\n", + " - sub_00010AB8 (74%)\n", + " - sub_00011354 (77%)\n", + " - _ITM_registerTMCloneTable (100%)\n", + " - _ITM_deregisterTMCloneTable (100%)\n", + " - __imp___gmon_start__ (100%)\n", + " - __imp_wbd_get_cli_command_id (100%)\n", + " - __imp_printf (100%)\n", + " - __imp_fputs (100%)\n", + " - __imp_wbd_json_create_cli_cmd (100%)\n", + " - __imp_stub_send_hld_hlpr (100%)\n", + "tm_block.cgi: 75% [matched:170][unmatched:1-1]:\n", + " - sub_00012E78 (63%)\n", + " - sub_000126E4 (98%)\n", + " - sub_00012DB8 (99%)\n", + " - _ITM_registerTMCloneTable (100%)\n", + " - __imp___gmon_start__ (100%)\n", + " - _ITM_deregisterTMCloneTable (100%)\n", + " - __imp_sprintf (100%)\n", + " - __imp_cmsMsg_send (100%)\n", + " - __imp_strcpy (100%)\n", + " - __imp_cmsMem_free (100%)\n", + "libcurl.so.4: 75% [matched:1644][unmatched:29-29]:\n", + " - Curl_select (0%)\n", + " - strerror (1%)\n", + " - sub_0002952C (1%)\n", + " - sub_00041510 (1%)\n", + " - Curl_sendf (2%)\n", + " - sub_000415A4 (2%)\n", + " - j_Curl_md5it (3%)\n", + " - sub_00029238 (4%)\n", + " - sub_0001C1C0 (5%)\n", + " - sub_00041C10 (5%)\n", + "libcurl.so: 75% [matched:1644][unmatched:29-29]:\n", + " - Curl_select (0%)\n", + " - strerror (1%)\n", + " - sub_0002952C (1%)\n", + " - sub_00041510 (1%)\n", + " - Curl_sendf (2%)\n", + " - sub_000415A4 (2%)\n", + " - j_Curl_md5it (3%)\n", + " - sub_00029238 (4%)\n", + " - sub_0001C1C0 (5%)\n", + " - sub_00041C10 (5%)\n", + "wps_pbcd: 77% [matched:236][unmatched:3-3]:\n", + " - sub_00017AB0 (7%)\n", + " - sub_00014FD8 (10%)\n", + " - sub_00014500 (42%)\n", + " - sub_00015D00 (52%)\n", + " - sub_00014078 (79%)\n", + " - sub_000143BC (79%)\n", + " - sub_00013604 (85%)\n", + " - sub_00011B88 (91%)\n", + " - sub_00015864 (92%)\n", + " - sub_00014EA0 (94%)\n", + "reset_pwd.cgi: 77% [matched:213][unmatched:1-1]:\n", + " - sub_00013308 (63%)\n", + " - sub_00012B74 (96%)\n", + " - sub_000130C0 (98%)\n", + " - sub_000151FC (98%)\n", + " - sub_00013248 (99%)\n", + " - _ITM_registerTMCloneTable (100%)\n", + " - __imp___gmon_start__ (100%)\n", + " - _ITM_deregisterTMCloneTable (100%)\n", + " - __imp_sprintf (100%)\n", + " - __imp_cmsMsg_send (100%)\n", + "libwbdshared.so: 78% [matched:789][unmatched:0-0]:\n", + " - wbd_tlv_decode_weak_client_response (15%)\n", + " - wbd_parse_cli_args (20%)\n", + " - wbd_tlv_encode_fbt_config_response (22%)\n", + " - wbd_ds_is_interface_dedicated_backhaul (23%)\n", + " - wbd_get_command_id (24%)\n", + " - j_wbd_get_command_id (30%)\n", + " - wbd_tlv_encode_weak_client_response (34%)\n", + " - wbd_ds_get_i5_device (34%)\n", + " - wbd_ds_interface_init (35%)\n", + " - wbd_tlv_encode_fbt_config_request (35%)\n" + ] + } + ], + "source": [ + "from ipywidgets import IntProgress\n", + "from IPython.display import display\n", + "from collections import Counter\n", + "from bindiff import BinDiff, BindiffFile\n", + "\n", + "diff_dir = Path(\"diffs/\")\n", + "\n", + "progress = IntProgress(min=0, max=len(list(diff_dir.iterdir())), description=\"Load diffs\")\n", + "display(progress)\n", + "\n", + "diffs = Counter()\n", + "for diff_file in diff_dir.iterdir():\n", + " progress.value += 1\n", + " diff = BindiffFile(diff_file)\n", + " diffs[diff_file] = diff.similarity\n", + " del diff # useful to free the memory\n", + "\n", + "# Reopen the most dissimilar binaries\n", + "for diff_file, similarity in diffs.most_common()[::-1][:15]:\n", + " diff = BindiffFile(diff_file)\n", + " binary_file = str(diff_file.name).split(\"_vs_\")[0]\n", + " print(f\"{binary_file}: {similarity:.0%} [matched:{len(diff.function_matches)}][unmatched:{diff.unmatched_primary_count}-{diff.unmatched_secondary_count}]:\")\n", + " fun_sims = Counter({x.name1: x.similarity for x in diff.function_matches})\n", + " for fun, sim in fun_sims.most_common()[::-1][:10]:\n", + " print(f\" - {fun} ({sim:.0%})\")" + ] + }, + { + "cell_type": "raw", + "id": "ed443260-5d27-44f0-b058-20d929ee786d", + "metadata": {}, + "source": [ + "
\n", + "

Open Question

\n", + "

Try to identify interesting components security-wise. Then try to identify ones that\n", + " have changed and into them what functions have changed.\n", + "

\n", + "
" + ] + }, + { + "cell_type": "markdown", + "id": "01f4f44e-5c2b-4219-85fc-151d44296b3b", + "metadata": {}, + "source": [ + "## Bonus\n", + "\n", + "The latest version released is [1.0.11.96](https://www.netgear.fr/support/product/rax30#download) which apparently provide a **\"hot fix\"**. Can you identify what has been patched and how ?" + ] + }, + { + "cell_type": "raw", + "id": "d6abb2a0-e210-462a-80af-f90573d02665", + "metadata": {}, + "source": [ + "" + ] + }, + { + "cell_type": "raw", + "id": "686cc7b6-fe51-40d0-8f22-1687df08ab45", + "metadata": {}, + "source": [ + "" + ] + } + ], + "metadata": { + "kernelspec": { + "display_name": "diffing", + "language": "python", + "name": "diffing" + }, + "language_info": { + "codemirror_mode": { + "name": "ipython", + "version": 3 + }, + "file_extension": ".py", + "mimetype": "text/x-python", + "name": "python", + "nbconvert_exporter": "python", + "pygments_lexer": "ipython3", + "version": "3.10.9" + } + }, + "nbformat": 4, + "nbformat_minor": 5 +} diff --git a/tutorials/tutorials.rst b/tutorials/tutorials.rst index c463fd9..0e08f29 100644 --- a/tutorials/tutorials.rst +++ b/tutorials/tutorials.rst @@ -14,8 +14,8 @@ Python-bindiff :maxdepth: 1 Symbols Porting <03a_diffing_porting_symbols.ipynb> - Automating a Diff - Batch Diffing + Full Firmware Diffing <04c_firmware_diffing.ipynb> + QBinDiff --------