There was quite a lot of reading last week…, so lets lighten it up a bit this week.
Curl yesterday had a heap-based buffer overflow released! Curl (if you haven’t heard of it) is one of those fundamental technologies holding up the internet; so it’s always interesting to see these severe bugs appearing…
Last week we talked about heap overflows and use after free bugs. Last summer, a brilliant exploit was demonstrated in the TAS Block of the Summer Games Done Quick speedrunning conference: Legend of Zelda Ocarina of Time Triforce Percent.
If you haven’t seen it, have an hour to spare and have a fondness for old Nintendo games (or are old enough to have been a kid in the 90s and spent many hours on the playground discussing if it was actually possible to get the Triforce in OoT…) I’d strongly recommend it.
It ends with a lovely note by the developers that hacking is often portrayed as being destructive… breaking systems. Yet their exploit is creative: by using hacking techniques they can create new games, new content, and make childish dreams come true.
As well as the run itself, theres also an explanation video of how it works.
These are all techniques we’ve been covering, and which you’ve been doing in the labs. Cool or what?
Describe at a high level how to gain arbitrary code execution with W^X memory by
using shellcode without using ROP. Hint: you’ll need to use
mprotect()
. (5 marks)
Write a ROP chain to set =rax= to 1 and =rbx= to 2. Assume you have access to the following gadgets:
xor_ab: xor rax, rbx ; rax = rax ^ rbx;
ret
xor_ba: xor rbx, rax ; rbx = rbx ^ rax
ret
pop_a: pop rax;
ret
(5 marks)
(15 marks)
e.g. stack buffer or environment variable (1).
Overflow stack buffer creating two stack frames
Set first frame to call mprotect marking the shellcode as executable (1)
Set second to call shellcode (1)
Yes you could quibble ret2libc is ROP in disguise. I’d propbably give a point for that very reasonable quibbling…
pop_a 2 xor_ab ; a = 2 ^ b; b = b xor_ba ; a = 2 ^ b; b = b ^ 2 ^ b = 2 (remember x ^ x = 0, and 0 ^ y = y) pop_a 1
It makes ROP slightly easier because you don’t need to defeat ASLR in order to find the gadgets. Leak the pointers to the gadgets from a program you write then on next run the offsets will still be the same and on running a different program they’re the same.