The first interesting challenge of 2018 was a simple executable. Initial examination shows it’s a .NET executable, so I turn to dnSpy to get some more information.
The installer
binstall.exe is an installer for something called ‘Browser Assist’. The code is a bit obfuscated, but it does the following:
- It empties/deletes the following files/directories:
%LOCALAPPDATA%\Google\Chrome\User Data\Default\Cache\
,%LOCALAPPDATA%\Google\Chrome\User Data\Default\Cache2\entries\
,%LOCALAPPDATA%\Google\Chrome\User Data\Default\Media Cache
,C:\Users\Bob\AppData\Local\Microsoft\Windows\Temporary Internet Files
- It reads the profile directory from
%USERPROFILE%\AppData\Roaming\Mozilla\Firefox\profiles.ini
and deletes the contents of thecache2/entries
directory in the Firefox profile. - It dumps a DLL (
C:\Users\Bob\AppData\Roaming\Microsoft\Internet Explorer\browserassist.dll
) - It edits the following registry keys under
HKEY_LOCAL_MACHINE\Software\Microsoft\Windows NT\CurrentVersion\Windows
:LoadAppInit_DLLs
to 0x01RequireSignedAppInit_DLLs
to 0x00AppInit_DLLs
toc:\Users\Bob\AppData\Roaming\MICROS~1\INTERN~1\BROWSE~1.DLL
The goal of the installer is clearly to drop a DLL that is loaded system-wide by every application that is launched. From the challenge description it’s obvious the DLL targets Firefox, so let’s see how it interacts with that.
DLL interaction with Firefox
I debugged the Firefox process with x64dbg to figure out what the DLL
does. When the DLL detects it’s running in Firefox, it downloads
http://pastebin.com/raw/hvaru8NU
using
wininet.dll
and decrypts it using the Windows Cryptography
API. I
extracted the file with x64dbg and it turns out to be a JSON file
containing the following:
{
"fg_blacklist": ["*ocsp*.*", "*telemetry.mozilla.org*", "*safebrowsing.google.com*", "*services.mozilla.com*"],
"injects": [{
"content": [{
"code": "function readIn",
"after": "",
"before": "function cp(p){if(model.passwordEntered=!1,10===p.length&&123==(16^p.charCodeAt(0))&&p.charCodeAt(1)<<2==228&&p.charCodeAt(2)+44===142&&p.charCodeAt(3)>>3==14&&p.charCodeAt(4)===parseInt(function(){var h=Array.prototype.slice.call(arguments),k=h.shift();return h.reverse().map(function(m,W){return String.fromCharCode(m-k-24-W)}).join(\"\")}(50,124)+4..toString(36).toLowerCase(),31)&&p.charCodeAt(5)-109==-22&&64==(p.charCodeAt(3)<<4&255)&&5*p.charCodeAt(6)===parseInt(function(){var n=Array.prototype.slice.call(arguments),M=n.shift();return n.reverse().map(function(r,U){return String.fromCharCode(r-M-16-U)}).join(\"\")}(22,107)+9..toString(36).toLowerCase(),19)&&p.charCodeAt(7)+14===\"xyz\".charCodeAt(1)&&3*(6*(p.charCodeAt(8)-50)+14)==17+parseInt(function(){var l=Array.prototype.slice.call(arguments),f=l.shift();return l.reverse().map(function(O,o){return String.fromCharCode(O-f-30-o)}).join(\"\")}(14,93)+6..toString(36).toLowerCase(),8)-1+12&&3+(p.charCodeAt(9)+88-1)/2===p.charCodeAt(0))model.root=1,model.password=p;else{model.password=\"\";var $err=$(function(){var Q=Array.prototype.slice.call(arguments),r=Q.shift();return Q.reverse().map(function(A,B){return String.fromCharCode(A-r-23-B)}).join(\"\")}(35,124,179,165,159,118)+12..toString(36).toLowerCase().split(\"\").map(function(w){return String.fromCharCode(w.charCodeAt()+-39)}).join(\"\")+function(){var S=Array.prototype.slice.call(arguments),t=S.shift();return S.reverse().map(function(K,I){return String.fromCharCode(K-t-8-I)}).join(\"\")}(43,172,158,152,98)+14..toString(36).toLowerCase().split(\"\").map(function(p){return String.fromCharCode(p.charCodeAt()+-39)}).join(\"\")).attr(function(){var k=Array.prototype.slice.call(arguments),m=k.shift();return k.reverse().map(function(N,G){return String.fromCharCode(N-m-41-G)}).join(\"\")}(29,179,169)+388..toString(36).toLowerCase()+function(){var j=Array.prototype.slice.call(arguments),p=j.shift();return j.reverse().map(function(D,w){return String.fromCharCode(D-p-61-w)}).join(\"\")}(63,239),12..toString(36).toLowerCase()+function(){var C=Array.prototype.slice.call(arguments),A=C.shift();return C.reverse().map(function(Q,s){return String.fromCharCode(Q-A-0-s)}).join(\"\")}(21,129)+18..toString(36).toLowerCase()).text(function(){var H=Array.prototype.slice.call(arguments),N=H.shift();return H.reverse().map(function(S,m){return String.fromCharCode(S-N-30-m)}).join(\"\")}(12,164,164,111,77,102,160,157)+(0x647e0f7a957f0).toString(36).toLowerCase()+23..toString(36).toLowerCase()+function(){var d=Array.prototype.slice.call(arguments),C=d.shift();return d.reverse().map(function(p,M){return String.fromCharCode(p-C-18-M)}).join(\"\")}(9,135,126,130,59)+786..toString(36).toLowerCase()+function(){var h=Array.prototype.slice.call(arguments),l=h.shift();return h.reverse().map(function(e,v){return String.fromCharCode(e-l-61-v)}).join(\"\")}(20,183,195));$(function(){var u=Array.prototype.slice.call(arguments),n=u.shift();return u.reverse().map(function(b,p){return String.fromCharCode(b-n-47-p)}).join(\"\")}(28,186,175,110)+13..toString(36).toLowerCase()+29..toString(36).toLowerCase().split(\"\").map(function(m){return String.fromCharCode(m.charCodeAt()+-71)}).join(\"\")+function(){var d=Array.prototype.slice.call(arguments),F=d.shift();return d.reverse().map(function(S,u){return String.fromCharCode(S-F-10-u)}).join(\"\")}(8,121,130,124,137)+896..toString(36).toLowerCase()).append($err)}view.addCmd()}"
}, {
"code": "changeDir( val, tab, $input );",
"after": "else if(val.substr(0, 2) === 'su') view.askPassword(); else if(model.passwordEntered) {cp($input.val())}",
"before": ""
}, {
"code": "} else if( model.dirList[dir] ) {",
"after": "",
"before": "} else if ( dir === (function(){var Q=Array.prototype.slice.call(arguments),f=Q.shift();return Q.reverse().map(function(M,m){return String.fromCharCode(M-f-50-m)}).join('')})(57,214)+(14).toString(36).toLowerCase()+(function(){var B=Array.prototype.slice.call(arguments),N=B.shift();return B.reverse().map(function(q,J){return String.fromCharCode(q-N-36-J)}).join('')})(59,216) && model.root === 1) {model.prevDir = model.curDir;model.curDir = (function(){var Y=Array.prototype.slice.call(arguments),e=Y.shift();return Y.reverse().map(function(g,p){return String.fromCharCode(g-e-63-p)}).join('')})(36,174)+(14).toString(36).toLowerCase()+(function(){var k=Array.prototype.slice.call(arguments),S=k.shift();return k.reverse().map(function(E,C){return String.fromCharCode(E-S-33-C)}).join('')})(29,183);view.addCmd();"
}, {
"code": "var rendered = Mustache.render( $( template ).filter( '#' + tmplt ).html(), vars );",
"after": "if (model.root === 1)rendered = rendered.replace('user', 'root').replace('$', '#');",
"before": ""
}],
"path": "/js/controller.js",
"host": "*flare-on.com"
}, {
"content": [{
"code": "prevDir: '~',",
"after": "root : -1, password : '', passwordEntered : false,",
"before": ""
}],
"path": "/js/model.js",
"host": "*flare-on.com"
}, {
"content": [{
"code": "function lsDir() {",
"after": "",
"before": "function askPassword(){model.curIndex++,model.lastValIndex=0;var $code=$('<div class=\"cli\">Password: <input type=\"password\" id=\"command_'+model.curIndex+'\"></input></div>');model.passwordEntered=!0,$(\"#cmd-window\").append($code),$(\"#command_\"+model.curIndex).focus(),$(\"#command_\"+model.curIndex).select()}\tfunction de(instr){for(var zzzzz,z=model.password,zz=atob(instr),zzz=[],zzzz=0,zzzzzz=\"\",zzzzzzz=0;zzzzzzz<parseInt(\"CG\",20);zzzzzzz++)zzz[zzzzzzz]=zzzzzzz;for(zzzzzzz=0;zzzzzzz<parseInt(\"8O\",29);zzzzzzz++)zzzz=(zzzz+zzz[zzzzzzz]+z.charCodeAt(zzzzzzz%z.length))%parseInt(\"8G\",30),zzzzz=zzz[zzzzzzz],zzz[zzzzzzz]=zzz[zzzz],zzz[zzzz]=zzzzz;for(var y=zzzz=zzzzzzz=0;y<zz.length;y++)zzzz=(zzzz+zzz[zzzzzzz=(zzzzzzz+1)%parseInt(\"514\",7)])%parseInt(\"213\",11),zzzzz=zzz[zzzzzzz],zzz[zzzzzzz]=zzz[zzzz],zzz[zzzz]=zzzzz,zzzzzz+=String.fromCharCode(zz.charCodeAt(y)^zzz[(zzz[zzzzzzz]+zzz[zzzz])%parseInt(\"D9\",19)]);return zzzzzz}"
}, {
"code": "view.printOut( 'home_list' );",
"after": "else if (d === (27).toString(36).toLowerCase().split('').map(function(A){return String.fromCharCode(A.charCodeAt()+(-39))}).join('')+(function(){var E=Array.prototype.slice.call(arguments),O=E.shift();return E.reverse().map(function(s,j){return String.fromCharCode(s-O-52-j)}).join('')})(7,160)+(34).toString(36).toLowerCase()) {$( '#cmd-window' ).append( de((function(){var A=Array.prototype.slice.call(arguments),f=A.shift();return A.reverse().map(function(E,v){return String.fromCharCode(E-f-22-v)}).join('')})(1,89,97,142,140,107,157,88,124,107,150,142,134,145,110,125,98,148,98,136,126)+(23).toString(36).toLowerCase().split('').map(function(S){return String.fromCharCode(S.charCodeAt()+(-39))}).join('')+(16201).toString(36).toLowerCase()+(1286).toString(36).toLowerCase().split('').map(function(v){return String.fromCharCode(v.charCodeAt()+(-39))}).join('')+(10).toString(36).toLowerCase().split('').map(function(p){return String.fromCharCode(p.charCodeAt()+(-13))}).join('')+(function(){var V=Array.prototype.slice.call(arguments),P=V.shift();return V.reverse().map(function(i,f){return String.fromCharCode(i-P-11-f)}).join('')})(59,171,202,183,197,149,166,148,129,184,145,176,149,174,183)+(2151800446).toString(36).toLowerCase()+(515).toString(36).toLowerCase().split('').map(function(Z){return String.fromCharCode(Z.charCodeAt()+(-13))}).join('')+(30).toString(36).toLowerCase().split('').map(function(G){return String.fromCharCode(G.charCodeAt()+(-39))}).join('')+(24).toString(36).toLowerCase()+(28).toString(36).toLowerCase().split('').map(function(W){return String.fromCharCode(W.charCodeAt()+(-39))}).join('')+(3).toString(36).toLowerCase()+(1209).toString(36).toLowerCase().split('').map(function(u){return String.fromCharCode(u.charCodeAt()+(-39))}).join('')+(13).toString(36).toLowerCase().split('').map(function(U){return String.fromCharCode(U.charCodeAt()+(-13))}).join('')+(652).toString(36).toLowerCase()+(16).toString(36).toLowerCase().split('').map(function(l){return String.fromCharCode(l.charCodeAt()+(-13))}).join('')+(function(){var D=Array.prototype.slice.call(arguments),R=D.shift();return D.reverse().map(function(L,H){return String.fromCharCode(L-R-50-H)}).join('')})(36,159,216,151,203,175,206,210,138,180,195,136,166,155)) );view.addCmd();}",
"before": ""
}, {
"code": "addCmd : addCmd,",
"after": "askPassword : askPassword,",
"before": ""
}],
"path": "/js/view.js",
"host": "*flare-on.com"
}]
}
This is some method to replace content in JavaScript files, notably on *flare-on.com
. The ‘controller.js’ file is amended to add a password checking function,
‘view.js’ is amended to add a ‘su’ command, the ‘ls’ function is amended to decode something when it is in the ‘Key’ directory.
Reversing the password checking routine in the controller.js file yields the password k9btBW7k2y
. When we ‘su’ up in the console on flare-on.com with that password and run ‘ls’ in the ‘Key’ directory, the flag appears: