Skip to content

Out-of-Bounds Read/Write Vulnerability in Register Access #22

@juckchang

Description

@juckchang

Description

Hello, I am reporting a vulnerability discovered during the analysis of this project, which was conducted as part of the IS-50601 course at KAIST.

There is an Out-of-Bounds Read/Write vulnerability in mac-improved/mac.c. The virtual machine fails to perform boundary checks on register indices when executing instructions. Consequently, an attacker can access indices outside the registers array, leading to arbitrary memory read and write capabilities within the process's data segment.

Vulnerable Code

The vulnerability occurs because the values fetched from the instructions array are used directly as indices for the registers array without validation.

case MOV: {
    // No check if instructions[IP+1] or [IP+2] are valid register indices
    registers[instructions[IP + 2]] = registers[instructions[IP + 1]]; // OOB Read & Write
    IP = IP + 2;
    break;
}

case SET: {
    // No check if instructions[IP+1] is a valid register index
    registers[instructions[IP + 1]] = instructions[IP + 2]; // OOB Write
    IP = IP + 2;
    break;
}

PoC
The following input demonstrates an OOB write using the SET instruction:

9 100000000 12345 0

9: SET Instruction
100000000: Target Register Index (OOB - causes arbitrary write relative to registers array)
12345: Value to write
0: HLT Instruction

Exploit Scenario

This vulnerability can be exploited to achieve Control Flow Hijacking.

  1. An attacker can use the MOV instruction to read existing addresses from the GOT into the VM's registers.
  2. By reading a libc address from the GOT, the attacker can use ADD or SUB instructions to calculate the offset to a target function. Finally, the attacker can use SET to overwrite a GOT entry with this calculated address, bypassing ASLR and taking control of the process.

Recommendation

A boundary check must be implemented before accessing the registers array. The index must be verified to be within the valid range (0 to REGISTER_SIZE - 1).

if (reg_index < 0 || reg_index >= REGISTER_SIZE) {
    // Handle error or terminate
}

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions