Don't like this style? Click here to change it! blue.css
As we move into exploiting the heap and more difficult problems I wanted to give you a mental model that can help you strategize in general.
The goal is here is to get you to think in terms of primitives little footholds in the path towards a full exploit. (This concept is why the realm of CVEs is so wide, anything that could possibly give a foothold is labelled. Actually using those potential weaknesses is a different story.)
I think every solution to every PWN must have a (sometimes trivial) strategy/solution to each of the following questions:
system("/bin/sh")
? A win()
? Maybe execve("cat flag.txt")
?fini_array
? Use the malloc_hook
or free_hook
?%n
? One of the heap primitives?This lets your assess your situation and your skillset in a very exponential way:
n_win
n_leak
n_rip
n_www
The number of distinct PWNs you can do/create/imagine is n_win * n_leak * n_rip * n_www
When scouting a potential PWN you need to find 1 answer in each of those four dimensions which takes: n_win + n_leak + n_rip + n_www
decisions on your part.
It also means that whenever you learn one new technique in any of the four you expand your power by a sort of n**3
growth rate.
Well, for n_win
we have seen "win functions", "ret to libc", "shellcode", "one_gadgets", "syscalls" maybe 5ish methods of popping a shell.
For n_leak
we have done a lot in "no-PIE" binaries (which may or may not count to our scorecard), and we've been "given leaks" a few times. For making leaks we've really only seen two methods so far: "read the GOT" and "printf stack scanning" I'll call our score 3 since knowing how to handle a leak is worth a little something.
For n_rip
we have essentially 3 now: overwriting the return address on the stack, overwriting GOT, and now SROP.
For n_www
we might have 3 at the moment: overwriting stack variables, printf using %n, and calling PLT["gets"]
So that means we can currently handle roughly 135 distinct types of PWN problems with the skills we've learned so far.
If we were to assess a new problem we'd have to see if one of our 5 styles of winning works + one of our 3 styles of handling randomization works + one of our 3 methods of controlling flow works + one of our 3 methods of editing memory is sufficient. So 14 glances at the binary is the most we would need to assess if it's one we know how to handle currently.
Also any time we pick up a fundamentally new technique it adds at least 27 new problem types to our range of solvable PWNs.
Clearly somethings are interactions between methods, like defeating randomness by reading a canary then smashing the stack with that canary value in place. Is that a technique that falls beteen the cracks of my model? Maybe, maybe it's leaking with printf and writing with BOF.
As we move into more complex attacks, weaknesses, techniques, and methods. You can take each new insight and decide which buckets it helps you with.
When you go to tackle a problem that requires you to learn a new method you can carefully log the primitives that you have at your disposal and collect those primitives into your exploit script as the tools you will weild.
If you aren't sure the entire attack that you will pull off you can at least chip away at parts you could handle and talk about those with teammates.
It also let's you kind of do a flow chart:
This flwo chart was made by ASMA last year, she's great.
I have never done an exploit which controls instruction flow using the .fini_array
, yet I've heard of other people doing it.
If I can pull off one of those exploits, add it to my quiver, then we will essentially do n_rip++
adding 45 entirely new solution methods to our overall competencies.
So maybe let's try a .fini_array
thing together?