GithubHelp home page GithubHelp logo

nccgroup / depthcharge Goto Github PK

View Code? Open in Web Editor NEW
243.0 16.0 15.0 9.41 MB

A U-Boot hacking toolkit for security researchers and tinkerers

Home Page: https://depthcharge.readthedocs.io

License: BSD 3-Clause "New" or "Revised" License

C++ 3.41% Makefile 0.41% Python 95.22% C 0.87% Shell 0.08%
u-boot security-tools embedded-systems

depthcharge's Introduction

Depthcharge

What is Depthcharge?

Depthcharge is a toolkit designed to support security research and "jailbreaking" of embedded platforms using the U-Boot bootloader. It consists of:

Project Documention

More information can be found in the online documentation for the Depthcharge project.

If you'd like to build this documentation for offline viewing, You can find the Sphinx-based documentation "source" in the doc directory.

Branches

The Depthcharge source repository contains two primary branches:

  • main - The latest release. This corresponds to what is available on PyPi
  • next - "Bleeding edge" changes scheduled for inclusion in the next release.

At each release, the contents of next are merged to main and tagged accordingly.

Under some circumstances, selected fixes may be merged to main in order publish an interim patch release.

Versioning

Depthcharge uses a Semantic versioning scheme for both the Python API and the Companion Firmware. The version number for published releases will follow that of the Python API version. The CHANGELOG shall document the current version state of both, along with any compatibility information.

Currently, this project uses "unstable" version numbers; API-breaking changes may occur within this minor version series, if deemed to be sufficiently beneficial for the future of the project. Refer to the CHANGELOG for guidance on handling any API changes.

Each published release will have a "codename". This serves no real purpose, other than to amuse the author and add a little fun to preparing releases. (Maybe they'll even be useful to remember!) The codenames are song titles from punk bands, increasing alphabetically with each release.

License

All Depthcharge components are licensed under the BSD 3-Clause License, found in the License.txt file. Project files use the corresponding SPDX Identifier to denote this.

Logo

The Depthcharge logo was created by the incredibly talented Juupiter.

depthcharge's People

Contributors

jynik avatar youssefms avatar

Stargazers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

Watchers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

depthcharge's Issues

Peripheral/Subsystem Access Identification

Along the lines of #21 -- I'd like to add some U-Boot image automation that can quickly locate accesses to memory-mapped SoC peripheral registers.

I envision creating a separate project and git repository to aggregate SoC memory maps (if one does not already exist), and then making that a Depthcharge dependency (or pulling it in as a subrepo).

By understanding what SoC-specific functionality the bootloader is using, one can gain insight into customization a vendor may have made, as well as what functionality is or is not in use (i.e. helping establish the attack surface).

For example, one of the more adorable custom U-Boot "protections" I've come across is the use of a debug enable GPIO pin that would allow the console to be access when the pin as asserted. I found this while reversing code dumped from the device's NOR,

Support an additional U-Boot version in the unlock bypass example

The unlock bypass example currently supports one specific version of the vendor-modified U-Boot build.

To make this more accessible and usable in training exercises, add support for an additional (or two) vulnerable versions.

The specific versions are TBD and will depend on devices I can purchase or borrow. (Always happy to accept a u-boot.bin dump!)

Create 'NoneLE32' and `NoneBE32` Architectures, set former as default

The current default for the architecture selection is ARM -- the only supported architecture.

As expected, all Hell breaks loose ๐Ÿ”ฅ when testing on a MIPS target. (This was largely the motivation for migrating to opt-in --allow-deploy / --allow-reboot semantics.)

To further make life a bit easier on "new" targets, Depthcharge should change the default to a 'NoneLE32' target that defines no GD location, no registers, etc -- nothing beyond 32-bit word size, 4-byte alignment (maybe 8?), and little-endiannes.

Should be trivial to toss in a NoneBE32 as well, albeit probably not tested and debugged well just yet.

cmdline.py: Migrate add_<x>_argument to **kwargs parameters

The (often absurd) parameters here have gotten out of hand, largely just to support some of my wacky automagic means to configure standard cmdline args in Depthcharge-based scripts.

For each of the add_<x>_argument(self, ...) functions, migrate each of these to use **kwargs instead of the inconsistent set of required, help, and default arguments.

As part of this, help text for each item should be moved to a local help_text definition, and the help text should be an overridable optional via self.add_argument(..., help=kwargs.get('help', help_text)

DataAbort parse failure

The "Mode" entry in an ARM data abort dump will contain an additional (T) entry if the device is in Thumb mode.

This triggers an unexpected failure because the assignment expects a name, value pair, but split(' ') is looking to provide three fields in this case.

Add U-Boot Config Checker

Implement a checker similar in usage/reporting to checksec and kconfig-hardened-check that ingests either a U-Boot .config or Depthcharge device configuration file and flags potentially risky enabled commands or configuration items.

Output options should include:

  • Pretty-printed tables
  • CSV
  • HTML tables

This work will undoubtedly help prioritize some additional depthcharge.Operation implementations, based on what we find to be most common across samples.

Project Logo Revamp

Spoiler Alert - Jon is a landlubber!

A Twitter user* astutely pointed out that the submarine used in our logo is actually not of the type that one would attack with depth charges. Per their note - "the periscope wouldn't be up...nor would it have fairwater planes. Should have gone for a Type VII or Gato class."

Noted for possible future logo revamp.

*Not sure if they want credit for their observation or to remain unnamed; erring on the side of caution.

Add option to disable payload loading

It's currently possible to specify that payload loading should be skipped (and instead that it's already deployed), but not specify that all payload deployment and execution should be disallowed.

Add this, and forcibly enter this state if payload_base is not user-provided and we don't have a $loadaddr environment variable.

Current "Reboot on Linux-looking prompt" behavior is unintuitive and counterproductive

The current code (v0.1.1post1) will attempt to issue a reboot command if Depthcharge encounters a prompt ending with $ or #, which might suggest we've booted to a Linux shell.

However, some vendors use these in their custom U-Boot prompt strings; this Depthcharge behavior is confusing and counterproductive for new users.

Opening this issue to track walking this functionality back, and making it an opt-in for folks who know that this is what they want. (As I often do when testing on devices that I've configured to boot to a root shell.)

Add CONFIG_ENV_IS_* support

Describe new feature

CONFIG_ENV_IS_NOWHERE can be enabled to prevent loading environment variables from external storage. It should be enabled, although if I understand correctly, the lack of any ENV_IS_IN_* flag will also enable this, so it isn't necessary as long as none of those are defined.

Describe the solution you'd like
Add a check to the configuration analyzer (depthcharge-audit-config) to look for any ENV_IS_IN_* being set without CONFIG_ENV_IS_NOWHERE being set.

Describe alternatives you've considered
None

Additional context
None

Documentation: Add "Extending Deptcharge" manual

I put quite a bit of elbowgrease into ensuring that Depthcharge can be "a tool for quickly building one-off tools". However, the current documentation does not adequately reflect this.

This issue tracker item is to track some ideas and progress on building out a guide on how to extend Depthcharge. I envision this including a good description the Operation.register() functionality, and a solid discussion of some of the class private data members that are leveraged. This also begs the question, which is "really private" vs "intended for use by folks extending Depthcharge at runtime"? -- which is something that should be tackled in a sane manner.

Create CI Pipeline for exercising `setup.py`

The next branch shouldn't be grossly broken in a manner reported in #72.

I need to set up a CI pipeline to, at a minimum, perform test of package installation:

  • python3 -m pip install .
  • python3 -m pip install -e .[docs]

md Read Failures on U-Boot 2012.10

Looks like the regex in memcmds.py is expecting 16 characters in the ASCII text portion of the hex dump output. (I believe newer versions pad up to a consistent line length)

    depthcharge.operation.OperationFailed:
        Failed to parse line: bff64d92: f7ff ffd5    ....

Add RemoteSerialConsole support

Add a depthcharge.console.Console subclass that operates on a remote Console instance over TCP.

It may make more sense to re-define depthcharge.console.Console as an abstract base class, with SerialConsole and RemoteSerialConsole implementations. Ideally, this would be done in a backwards compatible way that doesn't break existing scripts.

The use-case for this is remote access to lab environments or shared devices. This can assume the connection is already tunneled by an appropriately authenticated and encrypted channel (e.g. SSH), and only provide a simple TCP interface.

Companion Firmware: Add SPI Peripheral support

If I remember correctly, there are some power management commands in U-Boot that result in SPI transactions that could be leveraged by the Depthcharge Companion firmware.

Opening this issue to track this. Ideally I'd like to find a device in the wild to test against.

Migrate u-boot.py to a subpackage

The uboot.py file will quickly grow unwieldy as additions are added for v0.2.0 efforts.

This will be moved to a uboot subpackage, containing items such as env.py, jumptable.py, etc.

This will be an API-breaking change in the unstable v0.y.z series; guidance on changed API calls will be necessary in the release notes.

Add checkers for CVE-2022-30552 and CVE-2022-30790

Details available here:

https://research.nccgroup.com/2022/06/03/technical-advisory-multiple-vulnerabilities-in-u-boot-cve-2022-30790-cve-2022-30552/

Both appear relevant if u-boot/net/net.c includes __net_defragment() via CONFIG_IP_DEFRAG=y.

The patch for these appear to be in U-Boot commit b85d130ea0cac152c21ec38ac9417b31d41b5552. (I have not reviewed it.)

I'm anticipating the check will apply for version < 2022.07, as the above is already in the master branch.

If someone wants to track down when this net.c code was introduced, I'm happy to include a lower bound in the applicable version check.

Depthcharge `deploy_payload` should flush icache

Currently, icache is not being cleaned. As a result, when recompiling the payload and redeploying, erratic behavior is observed (e.g. payload randomly crashing or returning error code). In order to work around this, icache could be disabled with U-Boot command icache off when available; ideally Depthcharge should clean dcache followed by flushing icache whenever deploying payloads.

See https://community.arm.com/developer/ip-products/processors/b/processors-ip-blog/posts/caches-and-self-modifying-code

Add `global data` inspection payload helper

Currently, the host-side Python code drives global data structure inspection, provided a means to read the gd pointer (e.g. bdinfo, RegisterReader) and a MemoryReader implementation to read the gd structure and potential jump table.

Currently, the memory and register reader payloads must have the jump table address passed to them. This is fine for built-in payloads, given that it gives us more visibility into failures.

However, it's definitely desirable to allow payloads to be made more self-sufficient. The same general approach should be implemented as a payload helper that can be included in any new payloads. (I'm thinking a static inline function in payloads/include/u-boot.h)

Introduce Storage API

Currently, there's no API abstractions for non-volatile storage access. As is done in the read_nand.py example, it's up to the user to manually invoke available commands (e.g. nand) to perform NV storage accesses.

I would like to introduce an NV storage API, similar to that of the RAM-based MemoryReader and MemoryWriter.

However, the important differences (e.g. bad blocks, SoC-specific error correction) between different NV storage technologies (e.g., NOR, NAND, eMMC) and interfaces (e.g. parallel, SPI) will need to be taken into account. It may be more worth than is actually valuable to try to abstract that all away from the user -- I haven't decided.

Opening this issue tracker item to mull this over and happily accept feedback.

Implement File Droppers

The ability to plop down an initscript, replacement /etc/passwd, etc. can be valuable in getting an initial foothold in a platform's OS, from which further instrumentation and analysis can be conducted.

U-Boot has a fantastic amount of filesystem support that can be exploited when the requisite commands (e.g. ext4) are available.

I'm currently envisioning adding a FileDropper class to abstract away the details of the target FS, of two types:

  1. Usage of exposed console commands
  2. Custom payloads

The latter item is particularly exciting, as it will be a much better example of how powerful it can be to leverage "stand alone" program functionality. A good example would to document would how to build a positioning-independent implementation of some subset of target filesystem functionality, leveraging the existing U-Boot source code and knowledge of the gd layout.

-R Flag fails when running "MdCrashRegisterReader"

Encountered the following error while running command "inspect depthcharge-inspect --arch arm -A -R -c test.cfg -m term":

Error: No data abort content found in the following text:
00000001: 80ea0000 ....

The last part in the term output is the following:

Early malloc usage: 464 / 2000
fdt_blob = 0x3af69fb0
U-Boot> md.l 1 1
00000001: 80ea0000 ....
U-Boot> 03
U-Boot>

Depthcharge Version

Depthcharge Release 0.2.0 (main branch)

Target System

Device: Raspberry Pi 4 Model B
SOC: bcm283x
U-Boot: 2020.01 (Jan 06 2020 - 20:56:31 +0000)

Logs

See console log attached
console.log

ARM: U-Boot circa 2012/2013 used r8 for GD pointer

In arm.py we currently use r9, as modern U-Boot versions do. This was not always the case, so we need some means to switch between r8/r9 based upon version info, inference, or user override.

Example can be found in 2012.10 version I've seen in the wild, from:
http://arago-project.org/git/meta-arago.git?p=meta-arago.git;a=blob;f=meta-arago-distro/recipes-bsp/u-boot/u-boot_2012.10-psp05.06.00.00.bb;h=fa2183e5bd3639252ef337777d504161a0f6251b;hb=093a05bb850c8d6a1922acf996f57fce20a6cd0d

depthcharge-read-mem -a argument is required conflicting with docs

The documentation (depthcharge-read-mem --help) claims that:

  -a <value>, --address <value>
                        Target address to read from Default: 0x00000000

However, running depthcharge-read-mem without providing the -a option results in the following error:

depthcharge-read-mem: error: the following arguments are required: -a/--address

Python Module: Add bootX Executors

Currently, the only Executor implementation is GoExecutor.

It should also be possible to use boot* commands as such, provided that we automatically wrap payloads with the necessary headers.

Version change in next branch fails setup.py version check

Describe the bug

The "-dev" added to the version number in next branch python/depthcharge/version.py causes the version check in python/setup.py to fail.

Depthcharge Version

31042d5

Target System

Attempted install on Ubuntu 20.04
Python version: 3.8.5

Additional context

Suggested change to regex in python/setup.py:
r"__version__\s*=\s*'(?P<version>[0-9]+\.[0-9]+\.[0-9]+(-[a-zA-Z0-9]+)?)'"

Add MIPS support

Add MIPS support to /python/depthcharge/arch.py and perform validation on any garden-variety MIPS-based SOHO router.

Project Name Collides with Pre-existing "Depthcharge" Coreboot Payload for Chromebooks

Overview

It quickly came to my attention that in my attempt to be clever with the whole "Sinking U-Boots with Depthcharge" pun, I've inadvertently selected a project name that collides with the depthcharge Coreboot payload that's the successor to U-Boot on Chromebooks.

Personally, I am really attached to the name and part of me is really hoping the two identically named projects can coexist separately. However, I understand that this can definitely lead to some confusion having two projects in the world that use the term "payload" and related to (but not affiliated with) U-Boot.

As such, I just wanted to create a tracker item to publicly recognize this, gather my thoughts, mull over things a bit, and provide a single thread where any relevant stakeholders can easily make their thoughts known... if it's even remotely an issue to them.

Was this intentional?

No. I went through a bunch of really terrible names over the course of months, and this was the one that I finally was excited with.

I would like to be a good FOSS citizen and certainly do not wish to cause confusion for aforementioned projects.

Post Mortem - Jon! How did you manage to miss this?

When going through half a dozen (really terrible) project name candidates, I did honestly try to avoid collisions. Before finalizing on "Depthcharge" I was looking for other Python modules in PyPi and Linux distributions' package repositories, as well as subdomains on readthedocs.io.

My oversight appears to have been being so focused on the Python-centric and name availability in packaging/doc/distribution aspects that I failed to actually look for " U-Boot" In retrospect -- duh, Jon.

Who had the name first?

The other "depthcharge". Let's just say that I'm late to the party... as usual.

commit d3e73282eaf7b8420f0cd6ed1a4c60c039c1eb95
Author: Gabe B. <#snip#@google.com>
Date:   Sat Mar 10 18:58:29 2012 -0800

What is your plan, regarding this?

For now, I'm keeping the name as-is. It's a small project and an initial body of work that I plain to maintain and continue developing. In comparison to an 8 year-old codebase in a major FOSS project -- this is small potatoes and may not even be a blip on their radar. I certainly would like my work to grow and evolve, and thus feel it's important to at least have some sort of a plan.

At this time, I don't think the disambiguation is too hard...

Are you a security researcher analyzing and attacking U-Boot? You want this code.
Are you doing something with a Chromebook or Chromium project? This is not the code you're looking for.

If users of begin expressing actual confusion beyond "lol smooth move Jon" - I could together some disambiguation blurbs in the README and front page that redirects people looking for the Coreboot payload to the correct pages. (However, this could backfire and allow search engines to pick up more in bound links, only exacerbating the problem I've created.)

If it becomes painfully apparent that I am indeed creating significant consternation for the Chromium / Coreboot folks -- I will plan to transition the project to a new name before creating a 1.0.0 stable API release.

Suggestions are welcome. Amusing nautical puns are strongly encouraged.

Add AArch64 Support

Add AArch64 support to python/depthcharge/arch.py and validate on a common 64-bit ARM platform (e.g. Raspberry Pi 3, Model B).

setup.py broken by relative access of README.md

The attempt to keep the package long_description sync'd with README.md by opening and reading it in setup.py breaks the local pip install and ReadTheDocs generation, which run in different build directories.

Run-time payload registration

Currently, only built-in payloads can be used with Depthcharge.execute_payload. Need to provide a way to register custom user payloads at runtime.

Allow empty env or missing/broken printenv()

Currently, if we encounter an entirely empty environment or the printenv command doesn't work, we error our.

Opening a issue to track the fix for this; ideally we should just emit an error message but still try to finish initialization.

Function Identification

I'd like to be able to quickly identify "interesting" functions in a memory dump (e.g. hab_authenticate_image() ).

A lot can be achieved just through identification of unique strings in upstream code and identifying references to them.

At this time, I'm still debating whether this should actually be baked into the Depthcharge Python module. I am leaning towards "No" as it would require that I pull in something like Captone bindings as a dependency, and then proceeding to re-invent the wheel.

Instead, I think I'd instead prefer to invest this effort into IDA and Ghidra scripts, and potentially something using Ghidra's Headless Analyzer. Given that this project is intended to be a "toolkit" -- I think that this could be a perfectly reasonable approach.

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    ๐Ÿ–– Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. ๐Ÿ“Š๐Ÿ“ˆ๐ŸŽ‰

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google โค๏ธ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.