Skip to content

Instantly share code, notes, and snippets.

@BenGardiner
Last active January 2, 2023 14:38
Show Gist options
  • Save BenGardiner/a25296c7dde63013ac49c2aabfa8cc1b to your computer and use it in GitHub Desktop.
Save BenGardiner/a25296c7dde63013ac49c2aabfa8cc1b to your computer and use it in GitHub Desktop.
jupyter lab workspace for montrehack

Solving Zack Deveau's SNES NSec 2021 Challenges with radare2 and Jupyter Notebooks

Use files in this gist to make your own solve of these fun challenges by zdeveau! The extra challenge is that you must do it using only static analysis in radare2. To make things a bit easier on you we will use Jupyter (Labs) Notebooks.

Install the python (tested with python-3.10) packages you will need (a full tested pip freeze is in requirements.txt also):

pip3 install jupyterlab r2pipe

Then start with jupyter-lab (and open the url with token that it shows you).

Open the __your_solve.ipynb file in the browser UI of jupyter-lab and you will find a place to work on your own solution to the challenges. Start with this file. It will direct you to install a specific version of radare2:

git clone --depth=1 https://github.com/radare/radare2 && cd radare2
./sys/install-rev.sh v5.4.2

The rest of the files contain SPOILERS! Open them when following along with the training or you need spoilers to get un-stuck:

  1. _intro.ipynb -- concepts and tools, some steps to start
  2. hands-on-1.ipynb -- find the code handling the joypad reads and what are the magic joypad inputs?
  3. hands-on-2.ipynb -- find all the variable in memory tainted by correct button presses, follow the start button pressed code, flag the flag!
  4. hands-on-3.ipynb -- find the flag, find the code making ref to the flag, find the code tainting variables which are used by the code making ref to the flag, flag the flag!
Display the source blob
Display the rendered blob
Raw
{
"cells": [
{
"cell_type": "code",
"execution_count": 1,
"id": "4c7009a2-07f0-4c07-996e-4abe81a83c46",
"metadata": {},
"outputs": [],
"source": [
"# Copyright (c) 2022 Ben Gardiner\n",
"#\n",
"# Permission is hereby granted, free of charge, to any person obtaining a copy\n",
"# of this software and associated documentation files (the \"Software\"), to deal\n",
"# in the Software without restriction, including without limitation the rights\n",
"# to use, copy, modify, merge, publish, distribute, sublicense, and/or sell\n",
"# copies of the Software, and to permit persons to whom the Software is\n",
"# furnished to do so, subject to the following conditions:\n",
"#\n",
"# The above copyright notice and this permission notice shall be included in all\n",
"# copies or substantial portions of the Software.\n",
"#\n",
"# THE SOFTWARE IS PROVIDED \"AS IS\", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR\n",
"# IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,\n",
"# FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE\n",
"# AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER\n",
"# LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,\n",
"# OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE\n",
"# SOFTWARE.\n",
"\n",
"import r2pipe"
]
},
{
"cell_type": "markdown",
"id": "2442c9cf-2dfa-447b-9e0d-01ace068c480",
"metadata": {},
"source": [
"Tested with radare2 84e6cc6a21ec1c816d4d3eb3510d2cdc94330414 tag v5.4.2. Install this version of radare2 with \n",
"```shell\n",
"git clone --depth=1 https://github.com/radare/radare2 && cd radare2\n",
"./sys/install-rev.sh v5.4.2\n",
"```"
]
},
{
"cell_type": "markdown",
"id": "17328dad-b7e4-4241-b983-2cb69f3f7de0",
"metadata": {},
"source": [
"This notebook is for use in solving Zack Deveau's SNES challenges from NSEC 2021 during MontreHack! It is 'boilerplate' only. You will need to do the work!\n",
"\n",
"Here's a useful function to get you started... it will let you print radare2 commands in color from r2pipe. Very nice especially for disassembly"
]
},
{
"cell_type": "code",
"execution_count": 2,
"id": "4f0dd3f9-c84d-4752-9d98-e4f38600f62a",
"metadata": {},
"outputs": [],
"source": [
"def r2cmd(r, c):\n",
" '''\n",
" a simple wrapper for r2pipe command to allow 1) multi line commands and 2) colorized output (at least in jupyter notebooks)\n",
" '''\n",
" # force colorized output through r2pipe 🌈\n",
" r.cmd('e scr.color=true')\n",
" # use the best ANSI theme: bluy; no apologies to all the other trash themes ☜(゚ヮ゚☜)\n",
" r.cmd('eco bluy')\n",
" for a in c.strip().splitlines():\n",
" res = r.cmd(a)\n",
" if len(res) > 0:\n",
" print(res)"
]
},
{
"cell_type": "markdown",
"id": "e65da4d0-fec7-4cc4-95b0-671411aff8a6",
"metadata": {},
"source": [
"like this:"
]
},
{
"cell_type": "code",
"execution_count": 3,
"id": "d8f8cc86-96d4-43be-b59f-495843d53cc0",
"metadata": {},
"outputs": [
{
"name": "stdout",
"output_type": "stream",
"text": [
" \u001b[31m┌\u001b[0m\u001b[31m─\u001b[0m\u001b[31m<\u001b[0m 0x00000000 eb02 \u001b[33mjmp 4\u001b[0m\u001b[0m\n",
" \u001b[31m│\u001b[0m 0x00000002 58 \u001b[36mpop\u001b[96m rax\u001b[0m\u001b[0m\u001b[0m\n",
" \u001b[31m│\u001b[0m 0x00000003 c3 \u001b[31mret\u001b[0m\u001b[0m\u001b[0m\n",
" \u001b[31m└\u001b[0m\u001b[31m─\u001b[0m\u001b[31m>\u001b[0m 0x00000004 e8f9ffffff \u001b[40m\u001b[33mcall 2\u001b[0m\u001b[0m\n",
"\n"
]
}
],
"source": [
"r=r2pipe.open(\"-\", ['-n'])\n",
"r2cmd(r, \"\"\"\n",
"e io.cache = true\n",
"wx eb0258c3e8f9ffffff2f646174612f666c61672e747874\n",
"pd 4\n",
"\"\"\")"
]
},
{
"cell_type": "markdown",
"id": "40280d58-66ef-498a-b97b-f5dc9fe3e2df",
"metadata": {},
"source": [
"# Challenge 1"
]
},
{
"cell_type": "code",
"execution_count": 4,
"id": "949a272c-db19-4a7a-b84e-db06c7bc6fa0",
"metadata": {},
"outputs": [],
"source": [
"r = r2pipe.open('sequence_1.smc', ['-2']) # -2 closes stderr so we don't see as much whining from r2 -- remove that option for more"
]
},
{
"cell_type": "code",
"execution_count": 5,
"id": "0a243d40-111b-485a-b1a1-2cb706b7b456",
"metadata": {},
"outputs": [
{
"name": "stdout",
"output_type": "stream",
"text": [
"fd 3\n",
"file sequence_1.smc\n",
"size 0x400000\n",
"humansz 4M\n",
"mode r-x\n",
"format sfc\n",
"iorw false\n",
"block 0x100\n",
"type ROM\n",
"arch snes\n",
"baddr 0xffffffffffffffff\n",
"binsz 4194304\n",
"bits 16\n",
"canary false\n",
"retguard false\n",
"crypto false\n",
"endian little\n",
"havecode true\n",
"laddr 0x0\n",
"linenum false\n",
"lsyms false\n",
"machine Super NES / Super Famicom\n",
"nx false\n",
"os snes\n",
"pic false\n",
"relocs false\n",
"sanitiz false\n",
"static true\n",
"stripped false\n",
"va true\n",
"\n"
]
}
],
"source": [
"r2cmd(r,'i')"
]
},
{
"cell_type": "code",
"execution_count": 6,
"id": "74ff6756-ad9f-4923-87e4-c096ab16dc79",
"metadata": {},
"outputs": [],
"source": [
"# your solution goes here"
]
},
{
"cell_type": "markdown",
"id": "4eaf8767-26da-4adf-8703-9792aef7b6a8",
"metadata": {},
"source": [
"# Challenge 2"
]
},
{
"cell_type": "code",
"execution_count": 7,
"id": "5a7bc39c-79d2-44c1-868d-d20bb8f04e80",
"metadata": {},
"outputs": [],
"source": [
"r = r2pipe.open('sequence_2.smc', ['-2'])"
]
},
{
"cell_type": "code",
"execution_count": 8,
"id": "8c6dace2-ad19-45cd-8e15-a32de84b61e0",
"metadata": {},
"outputs": [
{
"name": "stdout",
"output_type": "stream",
"text": [
"fd 3\n",
"file sequence_2.smc\n",
"size 0x400000\n",
"humansz 4M\n",
"mode r-x\n",
"format sfc\n",
"iorw false\n",
"block 0x100\n",
"type ROM\n",
"arch snes\n",
"baddr 0xffffffffffffffff\n",
"binsz 4194304\n",
"bits 16\n",
"canary false\n",
"retguard false\n",
"crypto false\n",
"endian little\n",
"havecode true\n",
"laddr 0x0\n",
"linenum false\n",
"lsyms false\n",
"machine Super NES / Super Famicom\n",
"nx false\n",
"os snes\n",
"pic false\n",
"relocs false\n",
"sanitiz false\n",
"static true\n",
"stripped false\n",
"va true\n",
"\n"
]
}
],
"source": [
"r2cmd(r,'i')"
]
},
{
"cell_type": "code",
"execution_count": 9,
"id": "46852309-268a-4a5a-93d6-06369327cca3",
"metadata": {},
"outputs": [],
"source": [
"# your solution goes here"
]
}
],
"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.9.12"
}
},
"nbformat": 4,
"nbformat_minor": 5
}
Display the source blob
Display the rendered blob
Raw
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Display the source blob
Display the rendered blob
Raw
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Display the source blob
Display the rendered blob
Raw
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Display the source blob
Display the rendered blob
Raw
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Display the source blob
Display the rendered blob
Raw
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
View raw

(Sorry about that, but we can’t show files that are this big right now.)

View raw

(Sorry about that, but we can’t show files that are this big right now.)

View raw

(Sorry about that, but we can’t show files that are this big right now.)

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment