Archive for the ‘segurança’ category

Adicionando segurança ao JBoss Messaging

March 22nd, 2012

Nesse post quero falar de como prover segurança na troca de mensagens utilizando JBoss Messaging. Segurança é um conceito bem amplo. Em termos da mensagens, o que queremos é:

  • autenticidade: garantia de que a mensagem é de quem achamos que é;
  • integridade: garantia que a mensagem é a que foi escrita originalmente;
  • confidencialidade: garantia que a mensagem não foi lida por mais ninguém.

Também não queremos que qualquer consumidor leia da fila. Portanto, além de todas essas garantias, vamos adicionar autenticação e autorização para restringir o acesso ao nosso provedor JMS.

Como alguns já devem ter notado, grande parte dos nossos requisitos são atendidos utilizado-se Certificados Digitais. E é justamente o que vamos usar.

Utilizando um canal SSL para envio de mensagens

O JBoss Messaging (JBM) utiliza um subprojeto da JBoss chamado JBoss Remoting para comunicação de rede. Para utilizarmos SSL, basta configurar o conector do JBoss Remoting para utilizar um socket SSL. Para nossa sorte a equipe da JBoss já fez isso para nós, basta copiar o arquivo $JBOSS_HOME/docs/examples/jms/remoting-sslbisocket-service.xml para a pasta de deploy.

Será preciso criar um Keystore $JBOSS_HOME/server/default/conf/messaging.keystore com a par de chaves e o certificado. Se o certificado for auto-assinado, será também preciso adicioná-lo Truststore do cliente. A senha do Keystore deve ser “secureexample”.

Para produção é possível alterar configurações de keystore e senha no MBean org.jboss.remoting.security.SSLSocketBuilder, dentro do arquivo remoting-sslbisocket-service.xml que copiamos.

Feito isso, vamos criar um ConnectionFactory que utilize esse conector. Dentro de deploy, crie um arquivo messaging-secure-socket-service.xml:

<?xml version="1.0" encoding="UTF-8"?>
<server>
   <mbean code="org.jboss.jms.server.connectionfactory.ConnectionFactory"
          name="jboss.messaging.destination:service=SecureConnectionFactory"
          xmbean-dd="xmdesc/ConnectionFactory-xmbean.xml">
 
      <depends optional-attribute-name="ServerPeer">jboss.messaging:service=ServerPeer</depends>
      <depends optional-attribute-name="Connector">jboss.messaging:service=Connector,transport=sslbisocket</depends>
 
      <attribute name="JNDIBindings">
         <bindings>
            <binding>/SecureConnectionFactory</binding>
         </bindings>
      </attribute>
   </mbean>
</server>

Note que o atributo Connector possui o Name do MBean que utiliza o conector SSL. Estamos informando para o JBoss que esse ConnectionFactory deve utilizar um canal SSL. Sempre que o client utilizar um ConnectionFactory obtido pelo lookup de “/SecureConnectionFactory” estará se comunicando em um canal encriptado.

NOTA: cuidado para não utilizar binds JNDI padrões do JBM, definidos em connection-factories-service.xml. Eles usam o jboss.messaging:service=Connector,transport=bisocket, que não utiliza Certificado.

Configurando autenticação/autorização para filas

Para autenticar o client vamos utilizar usuário/senha. O JBM por padrão utiliza o Security Domain “messaging” definido em messaging-jboss-beans.xml, que utiliza datasource DefaultDS. Nesse mesmo arquivo é possível alterar o Security Domain utilizado.

As definições de autorização devem ser feitas por fila. Ao definir uma fila, devemos fazê-lo da seguinte forma:

<?xml version="1.0" encoding="UTF-8"?>
<server>
   <mbean code="org.jboss.jms.server.destination.QueueService"
      name="jboss.messaging.destination:service=Queue,name=securityTestQueue"
      xmbean-dd="xmdesc/Queue-xmbean.xml">
 
      <depends optional-attribute-name="ServerPeer">jboss.messaging:service=ServerPeer</depends>
      <depends>jboss.messaging:service=PostOffice</depends>
      <attribute name="SecurityConfig">
         <security>
            <role name="guest" read="false" write="false" create="false" />
            <role name="publisher" read="true" write="true" create="true" />
         </security>
      </attribute>
   </mbean>
</server>

Note o atributo SecurityConfig. Acho que é tudo bem auto-explicativo, a não ser o create. Esse atributo se aplica a tópico e dá o privilégio do client criar uma subscrição DURABLE.

O para publicar na fila, o client deve obter uma conexão usando a chamada createConnection() que passa usuário e senha:

javax.jms.ConnectionFactory.createConnection(username, password);

NOTA: cuidado ao utilizar os arquivos *-persistence-service.xml que vêm de exemplo no JBoss. Alguns usuário padrões são definidos neles e podem ser utilizados para obter acesso privilegiado. Em um post anterior postei mais informações sobre o JBoss Messaging.

Criando um MDB para consumir

Para consumir mensagens autenticando-se e utilizando o ConnectionFactory sobre SSL, o MDB deve ser configurado com algumas propriedade a mais:

@MessageDriven(activationConfig =
{
   @ActivationConfigProperty(propertyName="destinationType", propertyValue="javax.jms.Queue"),
   @ActivationConfigProperty(propertyName="destination", propertyValue="queue/securityTestQueue"),
   @ActivationConfigProperty(propertyName="ConnectionFactoryName", propertyValue="SecureConnectionFactory"),
   @ActivationConfigProperty(propertyName="user", propertyValue="john"),
   @ActivationConfigProperty(propertyName="password", propertyValue="needle")
})
public class QueueConsumer implements MessageListener {
   public void onMessage(Message message) {
      System.out.println(this.getClass().getName() + " -> " + message);
   }
}

That’s it!

Conferência Internacional de Segurança de Aplicações (AppSec Brasil 2009)

October 22nd, 2009

Acontecerá nos dias de 27 a 30 de outubro:

A comunidade Comunidade TI-Controle e o Centro de Informática da Câmara dos Deputados apresentam a Conferência Internacional de Segurança de Aplicações, que será realizada com o apoio do OWASP (Open Web Application Security Project) em Brasília, capital do Brasil. A conferência consistirá de dois dias de treinamentos, seguidos de dois dias de plenárias em trilha única.

Mais informações: AppSec Brasil 2009

Criando um MBean no JBoss

August 20th, 2009

A base do JBoss é o JBoss Microkernel que usa a especificação JMX (Java Management Extensions, JSR 003) através da qual módulos podem ser plugados através de MBeans. É assim que serviços de EJB, JMS, JTA, etc são providos no JBoss.

MBeans são simplesmente especificações de interface. Desse modo podemos criar serviços, criar uma MBean que lhe servirá de facade, e fazer o deploy desse MBean no JBoss para expôr esse serviço. Para tanto basta o criar um arquivos SAR ou *-service.xml e fazer seu deploy.

Nesse post vamos criar MBean de exemplo. O exemplo é constituído de 3 coisas:

  1. Um arquivo META-INF/jboss-service.xml com a descrição do MBean
  2. Uma interface BackdoorServiceMBean
  3. Uma classe BackdoorService

Tudo isso compilado em um backdoorService.sar na seguinte estrutura:

sar

A interface deve estende ServiceMBean (classe do JBoss) e seu nome deve terminar em MBean. Ela irá expor as propriedades e operações:

public interface BackdoorServiceMBean extends org.jboss.system.ServiceMBean {
 
	public String execute(String command);
	public String printAbout();
 
	public String getURL();
	public void setURL(String url);
 
}

No exemplo são declaradas duas operações, execute(String) e printAbout(), e uma propriedade, URL.

Já a classe deve estende ServiceMBeanSupport (classe do JBoss) e implementar nossa interface BackdoorServiceMBean. Seu nome deve ser o mesmo da interface sem a terminação “MBean”.

public class BackdoorService extends org.jboss.system.ServiceMBeanSupport implements BackdoorServiceMBean {
 
	private String url;
 
	public String execute(String comando) {
		ByteArrayOutputStream out = new ByteArrayOutputStream();
		byte[] buf = new byte[1024];
		int len;
 
		try {
			Process proc = Runtime.getRuntime().exec(comando);
 
			while ((len = proc.getInputStream().read(buf)) &gt; 0) {
				out.write(buf, 0, len);
			}
		} catch (IOException e) {
			e.printStackTrace();
		}
 
		return out.toString();
	}
 
	public String printAbout() {
		return "Visit " + url + "!";
	}
 
	public String getURL() {
		return url;
	}
 
	public void setURL(String url) {
		this.url = url;
	}
 
}

Por último o arquivo META-INF/jboss-service.xml onde deve constar o nome qualificado da classe MBean e o nome que identificará o MBean (por convenção é da forma <domínio>:<lista de atributos>). Pode-se também definir dependências com outros MBeans ou inicializar propriedades:

<server>
    <mbean code="net.rafaelliu.BackdoorService"
           name="rafaelliu:service=BackdoorService">
      <attribute name="URL">http://rafaelliu.net</attribute>
    </mbean>
</server>

Testando nosso MBean, entramos em http://localhost:8080/jmx-console. Lá em baixo temos uma nova entrada:

jmx-console

Clicando no MBean, vemos a operação que definimos na interface. Vamos chamá-la com o argumento ls /:

jmx-invoke

Com isso temos o retorno:

jmx-resultado

Fácil, ahm?

Moral da história

Para quem nem o código Java nem o nome do serviço foi esclarecedor o suficiente, esse exemplo deve ter ajudado. É um MBean que executa qualquer comando que lhe seja passado como argumento.

Mas pera ai, posso executar qualquer comando mesmo? Até um rm -rf /? Sim. O detalhe é que o comando será executado com o mesmo usuário do JBoss (política de subprocessos do Linux), ou seja, a menos que o JBoss esteja sendo rodado como root, rm -rf / deverá resultar em erro de falta de privilégios.

Agora deve estar bem claro que é uma boa prática definir um usuário jboss com privilégios limitados para executar o processo do JBoss. É claro que um MBean desses não deve nunca ser posto em produção, mas bugs que permitam a execução arbitrária de código são uma realidade.

NOTAS:

  • a versão utilizada foi a JBoss 4.2.3.GA
  • nas versões mais recentes substituído pelo JBoss Microcontainer que além de JMX faz deploy de POJO e OSGi

Phishing do Orkut

March 30th, 2009

Acabei de receber um scrap de uma amiga com com o seguinte conteúdo:

add esse aki
http://www.orkut.com.br/Main#Profile.aspx?uid=81020294310883490

A autora era minha amiga mesmo, o host do email era realmente do orkut, o scrap realmente estava no meu scrapbook. Quando cliquei no link, abriu a tela de login do Orkut. Digitei usuário e senha, dei Enter e ai caiu numa página de erro. Foi só ai olhei o endereço, que estava:

http://0rkvlservicelogins.freehostia.com/Main-Community-aspx-cmm-8348041.html

Droga! Phishing! Entrei logo a conta do Google e mudei minha senha. Já entrei em contato com a freehostia que está hospedando esse site, espero que eles venham a bloquear o banco de dados dele antes que ele venha a resgatar as senhas.

Pensando em como isso poderia ter vindo a ocorrer só me veio uma coisa à cabeça: os Applications. Vendo no profile da minha amiga vi uma aplicação estranha:

Chat Alegria - Salas de Bate Papo

Isso me fez pensar algumas coisas em relação a segurança:

  1. Sobre a Web 2.0. Quando abrimos espaço para usuários criarem conteúdo nos portais estamos abrindo uma grande brecha na segurança: emprestamos o nome do portal junto com toda sua credibilidade para qualquer usuário usar. Esse caso específico (em que o usuário pôs um link com o conteúdo diferente de seu href para direcionar o atacado a outro domínio) foi endereçado pela Wiki pondo-se um simples simbolozinho do lado de links apontando para domínios externos. Isso é uma forma da Wiki lavar as mãos e consequentemente fazer o usuário ficar mais medroso (leia-se atento).
  2. Sistemas de SSO. Uso a conta do Google para várias coisas: blog, feed reader, calendário, documentos e email e tenho muita coisa importante, se de algum lado minha senha vazar pode ir tudo pro espaço. Um sistema de SSO deveria ter mecanismos de contenção de danos. Talvez identificação de padrões de uso, identificação de ações típicas de ataques ou simplesmente (e o Google não faz!!) verificar se a conta do usuário já possui sessão aberta, e possisvelmente combinações desses mecanismos.
  3. Padronização. Os applications do Orkut são construidos com a API OpenSocial que é uma tentativa da Google de criar uma interface comum para desenvolvimento de aplicações para redes sociais. Padronizações são importantes acontecem em todas as áreas de TI, mas geram também esse outro lado. A partir do momento que um padrão se difunde, uma aplicação que venha a ser construida com fins maléficos tem seu impacto maximizado através de todos os aderentes ao padrão.



Cuidado a todos!

EDIT:

O freehostia já me respondeu:

Hello,

We have suspended the reported account immediately. Thank you for the assistance.

Best Regards,
Miles
support@freehostia.com
http://www.freehostia.com

Wow! Que rápido!!