Rating: 4.5
# Malware Testrun
`200pts` `131 solves` `Network`
-----
* *@author*: derbenoo
* *@note*: The original write-up is located here: [derbenoo.github.io/ctf/2017/08/08/sha2017_ctf_malware_testrun/](https://derbenoo.github.io/ctf/2017/08/08/sha2017_ctf_malware_testrun/)
-----
## Challenge Description
We heard a rumour that our website will be used to distribute malware. We believe we captured a test run of it. Can you find out what the malicious content will be?
`malwaretestrun.tgz 53eff0e472db7ecfdd9a9534d3b05098`
## Overview
The provided archive file contains the `malware-testrun.pcap` file which we extract and open in Wireshark. It looks like an HTTP request for the website `http://obamamemes.com` was recorded with all subsequent requests the browser performed to fetch the referenced resources (pictures, CSS & Javascript files). We use Wireshark's `File -> Export Objects -> HTTP` dialog to dump all resources into a folder and have a closer look. We reconstruct the folder structure of the webserver and have a look at the index.html (named '/' by Wireshark):
![index.html after reconstructing the web servers folder structure](https://derbenoo.github.io//public/images/ctf/sha2017_ctf_malware_testrun_index.jpg)
After enjoying some premium quality Obama memes (where is Biden though???), we turn our focus to the advertisements that are displayed on the page. We inspect the ads.html file and quickly figure out that there is some shady Javascript magic going on:
``` Javascript
<script type="text/javascript">
eval(atob(document.images[0].src.replace(/.*,/, "")));
```
## De-obfuscating the first layer
So the source of the picture, which is base64 encoded data, is decoded and the resulting string is fed into an `eval()` call. We decode the data ourselves and find some compressed Javascript:
``` Javascript
z="";function v(b){s='';for(i=0,l=b.length;i<l;i+=8){c=0;for(j=7;j>=0;j-=1){c+=b[i+7-j]<<j;}s+=String.fromCharCode(c);}return s;}function d(img){i=0;l=img.length;st=[];while(i<l){st[i]= img[i*4]&1;i+=1;}return v(st);}function f(){w=i.naturalWidth;h=i.naturalHeight;c=document.createElement("canvas");x=c.getContext("2d");c.width=w;c.height=h;x.drawImage(i,0,0,w,h);t=d(x.getImageData(0,0,w,h).data);if(t=t.match(/SHA.*SHA/)){z+=t[0].replace(/SHA/g,'');}};function q(){i=new Image();i.addEventListener('load',f,false);i.src="notit.png"}setTimeout(q,1000);function a(){eval(z)}setTimeout(a,200000)
```
We use _jsbeatuifier.org_ to make the code more readable and replace the Javascript of the ads.html with the extracted one. After some analysis, we figure out that the script performs the following steps:
* After one second, create an image with the source `notit.png` and execute function `f()` when the image has been loaded
* `f()` creates a canvas, transfers the loaded image's data onto the canvas and then performs some weird operations on those data to transform them to a string.
* If the extracted string contains the keywords 'SHA', it extracts everything between the two occurrences and adds it to the variable `z`
* After a huge timeout, call `eval(z)`
By now it is pretty clear what we have to do, replace the `eval(z)` call with `console.log(z)` and set the huge timeout to something reasonable like 2 seconds. We let the script run and check our console output. At this point, we have to switch to Firefox because Chrome is very smart and prevents the script from running:
> Uncaught DOMException: Failed to execute 'getImageData' on 'CanvasRenderingContext2D': The canvas has been tainted by cross-origin data.
Cool stuff, anyways let's check what the script does when being executed:
``` Javascript
alert('Sorry, wrong image file!');
```
## De-obfuscating the second layer
So the script is working but we got the wrong image file, so we simply try all other images by replacing `i.src = "notit.png"` with the appropriate path and see whether anything useful is being parsed out of the image. We start with the `ad00_.png` files as they are also PNG files, the script was located in the ads.html file and we suspect the theme of the challenge to be malvertising. Indeed, the `ad001.png` actually contains something:
```
(+(+!+[]+[+[]]+[+!+[]]))[(!![]+[])[+[]]+(!![]+[][(![]+[])[+[]]+([![]]+[][[]])[+!+[]+[+[]]]+(![]+[])[!+[]+!+[]]+(!![]+[])[+[]]+(!![]+[])[!+[]+!+[]+!+[]]+(!![]+[])[+!+[]]])[+!+[]+[+[]]]+(+![]+([]+ ... )[+!+[]+[+[]]]+(+
```
Good old [jsfuck](https://github.com/aemkei/jsfuck/blob/master/jsfuck.js). We notice however that the end of the string is not properly terminated, it looks like there is a second part! Indeed, `ad002.png` and `ad003.png` also contain jsfuck code. We suspect that we have to chain them all together to get the full deal, so we write a for loop around the string extraction:
``` Javascript
for(index= 0; index< 8; index++){
function q(image_file) {
i = new Image();
i.addEventListener('load', f, false);
console.log("image file: "+image_file);
i.src = image_file
}
setTimeout(q, 1000+1000*index, "images/ad00"+index+".png");
function a() {
console.log("EVAL: "+z);
}
}
setTimeout(a, 10000);
```
The script runs through and prints valid jsfuck code into the console! We quickly head over to _jsfuck.com_, copy paste the code into the text area, **turn off the 'Eval Source' checkbox** and click "Run This". A nice alert box appears that contains our flag:
```
"x=new Date();if(x.getDate()=="23"&&x.getHours()=="12"){alert("flag{02aa1488771e325eef9b0e5f0d2db626}")}"
```
Nice, here's our flag: `flag{02aa1488771e325eef9b0e5f0d2db626}`