Giter Club home page Giter Club logo

jitboy's People

Contributors

hexrabbit avatar jserv avatar rinhizakura avatar rodrigodd avatar rofl0r 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

jitboy's Issues

security: Out-of-bound r/w lead to arbitrary code execution

Background

By design, the Gameboy has only 16 bits of addressing space, which means that no matter how large the memory is, the CPU can only access a maximum range of 0x0000 - 0xFFFF (64KB). Unfortunately, this addressing space is not only allocated to ROM and RAM but also to peripheral devices (such as audio and video output) that are mapped through MMIO, which also occupies part of the space.

This means there's less resources can be placed on ROM or loaded into RAM, so the banking mechanism is designed to solve this problem.

The concept of bank switch is to map an unaddressed memory location (e.g. 0x18000 - 0x19FFF) to a memory space (e.g. 0xA000 - 0xBFFF) where the bank can be switched freely, and then by controlling the current bank number through a register to switch between banks.

The location of the RAM / ROM bank can be found in the specification:

  • ROM: 0x4000 - 0x7FFF
  • RAM: 0xA000 - 0xBFFF

There are many types of Gameboy cartridges (e.g. MBC2, MBC3 ... etc.) and they offer different sized banks. For example, if you write X to any address from 0x0000 to 0x3FFF of an MBC2 cartridge, the ROM bank number will be switched to X. (reference)

This part is implemented in gb_memory_write() to support different cartridge types.

Vulnerabilities

The bug exist in two place in the jitboy RAM bank implementation:

  • MBC3 handler: An off-by-one flaw, since MBC3 supports only 4 RAM banks (0 ~ 3), the comparison should be value < 4, without the equal sign.
  • MBC5 handler: MBC5 supports up to 16 RAM banks, however there's no any check against the value variable.

If we trigger a write to ROM on some specific memory address range (e.g. ld (0x4000), A), the instruction will be translated by DynASM (at here, here) into gb_memory_write() and further be compiled into the jitted function, finally got executed during emulation.

Since mem->ram_banks is initialized with a fix-sized heap buffer (MAX_RAM_BANKS * 0x2000 == 4 * 0x2000), only 4 RAM banks are reserved for the emulator, so either MBC3 or MBC5 handler could cause a OOB (out-of-bound) access on heap, and by this primitive we can leak addresses and write to any function handler allocated on heap to control the execution flow.

Exploitation

After the vulnerability is found, I manually fuzzed the heap to find crashes, luckily I found a easy one to exploit.

image

It crashed on an instruction call qword ptr [rax+0x1d0], and since we can control the memory on both rax+0x1d0 and rdi point to, this is an easy win for system("/bin/sh").

https://github.com/HexRabbit/CTF-writeup/blob/master/2022/EOFCTF-qual/pwnboy/exp/exploit.c

My exploit starts with a bank switch to place out-of-bound heap memory into external memory (0xA000 - 0xBFFF), then leak the libc addresses and search the heap for a specific function table used by SDL2 library, which will be called during the screen rendering process.

After gathering addresses, next step is to calculate system() function address by some easy math, however it looks like the compiler GBDK only support up to 16 bit arithmetics, therefore I need to implement big number (64bit) addition/subtraction myself lol.

Finally, modify the function pointer to system() and place the argument "/bin/sh" for it, trigger the bank switch to write back the modified heap memory to pop a calculator!

tetris crashes

playing tetris (W) 1.1 (md5sum: 982ed5d2b12a0377eb14bcdc4123744e), the jit segfaults once the blocks pile up to the top. gdb backtrace was inconclusive so supposedly it's in jitted code.

unrelated question in order not to open another issue: is GBC support planned ?

Prepare CI/CD

After #15 is merged, it is time to think of the continuous integration and delivery (CI/CD).

Expected output:

  1. Enable GitHub Actions.
  2. Build jitboy each time when new commits / pull requests arrive.
  3. Run instruction compliance test suite and generated the corresponding report.

no instruction takes 4 bytes.

you mention a few times in the README.md file that instructions are 1 to 4 bytes. they are actually 1 to 3 bytes, the longest ones having an opcode and an immediate with 16 bits. the prefixed operations dont take an immediate value so they all take 2 bytes.

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.