Imagine the following vulnerable code
int getNumber(int* array, int index) {
return array[index];
}
int main(int argc, char** argv) {
int myArray = malloc(10 * sizeof(int));
myArray[0] = 1;
myArray[1] = 5;
printf("%d\n", getNumber(myArray, atoi(argv[1])));
}
Clearly, running the program with ./hello 11
is going to cause the program to either crash or dump something in memory. However, is there any way to exploit this program to run arbitrary code (at the privileges of the program)? Or is the only way of achieving code execution from this type of exploit be using this to get a memory dump which can be disassembled into the full codebase?
It's undefined behavior.
You can make some general guesses on how the heap and compiler are implemented. Within that boundary, you might limit the range of impact somewhat to "just how bad" it is likely to be able to get (a crash, usually, for this). But outside of guessing...to hack effectively you'd need to have a disassembly to know what instructions the compiler generated for that code...and have a lot of data about the system to line that up with.
The likely exploit is if you have a broader picture of the program, and some variables the programmer didn't expect you could modify that you manage to modify--within the scope of sandboxing that the OS trusts. You showed us a very short program that's unlikely to have much to exploit. But if it were a bigger program, with more functionality, and somewhere declared
int privilegeLevel = 2;
...you might manage within the process boundary of the program to overwriteprivilegeLevel
to 1 (let's imagine that gives you more capabilities than was expected, lower=better). Then you're exploiting some level of trust that was given to the program based on the belief that it didn't have such bugs.Basically: being able to write random junk in memory is only of value if you can write somewhere that something sees and acts on. Most modern systems separate code and data segments, and processes from each other. So the odds are slim of being able to figure out what magic number for
argv
is that would let you poke bytes somewhere they would be executed (as instructions) or acted upon (as data) by another process.The easiest exploit is generally just "we crashed U". But the more primitive the system, the more likely you could find the offset where the program loaded itself, notice consistent properties of where malloc put things, and perhaps use some negative number and start writing into kernel or code. In more sophisticated systems, arbitrary execution needs a bit more of a vulnerability than something this small in isolation.
I am following the "information is good" policy in offering such advice. Be ethical.