Basically the magic gadget is some code residing in the libc which is opening a shell when being executed. This can be used when trying to do a ret2libc in a ROP-style-exploit.
The magic gadget code has to either call execve or issue the corresponding syscall directly, while /bin/sh is set as first argument.
Overview (AMD64):
-
execve
- rdi: Pointer to /bin/sh
- rsi: Pointer to argv
- rdx: Pointer to env
-
syscall
- rax: Syscallnumber of execve: 59 oder 0x3b
- rdi: Pointer to /bin/sh
- rsi: Pointer to argv
- rdx: Pointer to env
Is a little python-script that uses radare2 and r2pipe-python, to find such magic gadgets automatically for a given libc.
$ ./magic.py libc-2.19.so
[x] Analyze all flags starting with sym. and entry0 (aa)
[x] Analyze len bytes of instructions for references (aar)
[x] Analyze function calls (aac)
[*] Use -AA or aaaa to perform additional experimental analysis.
[x] Constructing a function name for fcn.* and sym.func.* functions (aan)
Searching 7 bytes from 0x00000270 to 0x003aaa20: 2f 62 69 6e 2f 73 68
Searching 7 bytes in [0x270-0x3aaa20]
hits: 1
----------------------------------------------
Found /bin/sh @ 0x001639a0
----------------------------------------------
0x00041374 488b052d3b3600 mov rax, qword [rip + 0x363b2d]
0x0004137b 488d3d1e261200 lea rdi, qword [rip + 0x12261e]
0x00041382 488d742430 lea rsi, qword [rsp + 0x30]
0x00041387 c7052f61360000000000 mov dword [rip + 0x36612f], 0
0x00041391 c7052961360000000000 mov dword [rip + 0x366129], 0
0x0004139b 488b10 mov rdx, qword [rax]
0x0004139e e86d8f0700 call sym.execve
----------------------------------------------
Here's your magic gadget:
Offset: 0x00000000041374
Unfortunately, at the moment magic.py only works on the x86/x86-64 architecture.
- Test with more libcs (especially 32bit)