terça-feira, 28 de junho de 2011

Introdução à linguagem PERL

A sigla PERL significa "Practical Extraction And Report Language". Tal linguagem permite a criação de programas em ambientes UNIX, MSDOS, Windows, Macintosh, OS/2, e em outros sistemas operacionais.


Trata-se de uma linguagem que possui funções muito eficientes para manipulação de textos, o que a torna muito popular para programação de formulários WWW, além de ser muito utilizada em tarefas administrativas de sistemas UNIX, onde a linguagem nasceu e cresceu.


A linguagem PERL está sendo amplamente utilizada por ser rápida, eficiente e de fácil manutenção na programação de uma ampla faixa de tarefas, particularmente aquelas que envolvem manipulação de arquivos de texto. Além disso, existem muitos programadores de PERL compartilhando seus códigos abertamente.


Um exemplo da aplicação prática da linguagem PERL envolve a manipulação de arquivos ASCII, principalmente as páginas de Internet que se modificam dependendo de dados fornecidos pelo usuário. Um pequeno código PERL é capaz de realizar muitas ações.


Em termos de linguagem de programação, isso geralmente significa que o código será difícil de ler e penoso de escrever. Mas, embora Larry Wall - autor da PERL - afirme que a linguagem seja mais funcional do que elegante, a maioria dos programadores rapidamente descobre que o código PERL é muito legível. Podemos dizer, portanto, que uma das grandes qualidades da linguagem PERL é unir eficiência à disponibilidade de utilização.


Muitos questionam se os programas em PERL são compilados ou interpretados. De fato, a PERL é um pouco especial a esse respeito, podendo-se dizer informalmente que existe um compilador que pensa ser um interpretador. Existe um estágio de otimização em que o código de programa é compilado e transformado em código executável para que a linguagem seja realmente eficiente.


Entretanto, ela não grava esse código em um arquivo executável separado. Ao invés disso o código executável apenas é copiado pra memória, sendo depois utilizado. Isso significa que a PERL combina o ciclo de desenvolvimento rápido de uma linguagem interpretada com a execução eficiente de um código compilado. Essa necessidade de se compilar o código cada vez que o programa é executado é uma desvantagem, entretanto isso faz com que os desenvolvedores sejam obrigados a distribuir sempre seus códigos-fonte para os usuários.


De qualquer maneira, a fase de compilação é muito rápida, sendo possível que nem se note uma demora entre a ativação do script PERL e o início da execução. Em síntese, decidiu-se pela utilização dessa linguagem na implementação deste projeto principalmente por sua extrema capacidade em manipular arquivos de texto e pela boa interação que possui com a Internet, recursos que se sobressaem às possíveis desvantagens citadas.

Desenvolvimento WAP com PHP

Este artigo foi o objeto principal de um curso realizado em Brasília para os servidores públicos federais pelo Ministério da Saúde e o ITI (Instituto Nacional de Tecnologia da Informação)
Está em formato PDF.

Artigo

Autenticação de usuário e senha em PHP

Abaixo escrevi uma rotina simples para verificar se o nome e senha do usuário são válidos.
Caso sejam válidos, a página mostra o conteúdo restrito.
Caso os dados informados sejam inválidos, a página chama uma outra página mostrando falha de autenticação (um arquivo simples em formato html informando dados incorretos).

1)Crie um arquivo chamado verifica.php
contendo o código abaixo:


if (($usuario=="master") && ($senha=="12345"))
{
?>

// aqui mostra o conteúdo restrito


//caso o usuário e senha sejam inválidos, o código abaixo mostra
a página contendo erro de autenticação
}
else {
?>

}
?>


Pronto. Está criado uma rotina de autenticação para usuário. Caso deseje efetuar cadastros de usuários e senhas, aconselho utilizar um banco de dados, sugiro o MySQL, pois é free e atende muito bem as características do Php.

Bom estudos,
um grande abraço,

Autor: Reiner Franthesco Perozzo

Utilizando uniões em C

Como sabemos, costuma-se utilizar estruturas (struct) para armazenar informações relacionadas. Quando você cria uma estrutura o programa armaneza espaço em memória suficiente para conter todos os dados daquela estrutura. No entanto, algumas vezes você pode querer usar apenas um dado de cada estrutura.

Por exemplo: numa estrutura que indica horas trabalhadas (para funcionários de escritório) e produção (para empregados que ganham por comição) você vai utilizar apenas um dado da estrutura, ou ele é funcionário de escritório ou de produção. Utilizando o operador union você faz com que o programa armazena espaço suficiente para o maior dado, pois somente será armazenado um. Com isso você economiza bastante recurso de memória.

É bom deixar claro que esse recurso somente é válido quando você armazena apenas um dado na estrutura. O exemplo abaixo mostra os dados de um empregado
union escricao {
int numerocrea;
int numerocgc;
int numerooab;
}

Listas duplamente encadeada, circular e ordenada

/* montagem de uma lista duplamente encadeada e circular */
/* podendo ser ordenada ou de inserção ao final com o o uso da função insere('M') ou insere('F') */

#include
#include
#include

typedef struct nodo{
char nome[30];
char fone[15];
struct nodo *anterior, *proximo;
}lista;

lista *primeiro, *atual, *anterior, *proximo, *gravar;

void insere(char tipo){

if(primeiro == NULL){
primeiro = malloc(sizeof(lista));
primeiro->proximo = gravar;
primeiro->anterior = gravar;
gravar->anterior = primeiro;
gravar->proximo = primeiro;
}
else{
if(tipo == 'M'){
atual = primeiro->proximo;

while(strcmp(gravar->nome,atual->nome) > 0){
if(atual != primeiro)
atual = atual->proximo;
else
break;
}
anterior = atual->anterior;

proximo = atual; /* o endereço de atual vai para proximo */

anterior->proximo = gravar; /* Os dados contidos em "gravar" serão inseridos entre */
gravar->anterior = anterior; /* as os nodos referencia "anterior" e "proximo" */
gravar->proximo = proximo;
proximo->anterior = gravar;
}
if(tipo == 'F'){
anterior = primeiro->anterior;
proximo = primeiro;

anterior->proximo = gravar; /* Os dados contidos em "gravar" serão inseridos entre */
gravar->anterior = anterior; /* as os nodos referencia "anterior" e "proximo" */
gravar->proximo = proximo;
proximo->anterior = gravar;
}
}
}

void NovoReg(void){
system("cls");

gravar = malloc(sizeof(lista));

printf("Nome: ");
gets(gravar->nome);
printf("\nFone: ");
gets(gravar->fone);


insere('M'); /* chamada do procedimento de inserção */
/* 'M' corresponde a inserção no meio ( acarretando em encadeamento ordenado) e */
/* 'F' corresponde a inserção no fim */

printf("\nSeu registro foi incluido!\n\n");
system("pause");
}

void listar(void){
char op;

if(primeiro == NULL){
system("cls");
printf("Nenhum registro armazenado...\n\n");
system("pause");
return;
}
else{

atual = primeiro->proximo;

do{
system("cls");

printf("Pressione + e - para alternar entre os registros e para sair.\n\n");

printf("Nome: %s\n\nFone: %s\n",atual->nome,atual->fone);

op = getch();

switch (op){
case 43:{
if (atual->proximo == primeiro)
atual = primeiro->proximo;
else
atual = atual->proximo;
break;
}
case 45:{
if(atual->anterior == primeiro)
atual = primeiro->anterior;
else
atual = atual->anterior;
}
}

}while(op != 27);
}
}

void excluir(void){
char op;

if(primeiro == NULL){
system("cls");
printf("Nenhum registro armazenado...\n\n");
system("pause");
return;
}
else{

atual = primeiro->proximo;

do{
system("cls");

printf("Pressione + e - para alternar entre os registros, sair e confirmar\n\n");

printf("Nome: %s\n\nFone: %s\n",atual->nome,atual->fone);

op = getch();

switch (op){
case 43:{
if (atual->proximo == primeiro)
atual = primeiro->proximo;
else
atual = atual->proximo;
break;
}
case 45:{
if(atual->anterior == primeiro)
atual = primeiro->anterior;
else
atual = atual->anterior;
}
}

}while((op != 27) && (op != 13));
}

if(op == 27)
return;

printf("\n\nVoce confirma a exclusao deste registro (S/N): [ ]\b\b");
op = getch();

if (op >= 97)
op -= 32;

if(op == 'S'){
anterior = atual->anterior;
proximo = atual->proximo;

anterior->proximo = proximo;
proximo->anterior = anterior;

free(atual);

if (primeiro == primeiro->proximo) /* se for excluido o penultimo registro, sobrando apenas o registro "primeiro" */
primeiro = NULL; /* que não é util para nós, o primeiro tambem será liberado */
printf("\n\nRegistro excluido com sucesso!\n\n");
system("pause");

}
else
return;

}

int main(void){
char escolha;

do{
system("cls");

printf("I - Inclui\nC - Consulta\nE - Exclui\n - Sair\n\nEscolha[ ]\b\b");
escolha = getch();

if(escolha >= 97)
escolha -= 32;

if(escolha == 'I')
NovoReg();
if(escolha == 'C')
listar();
if(escolha == 'E')
excluir();

}while(escolha != 27);

return 0;
}

Menu em C com switch

Nesse tutorial, você irá aprender a utilizar menus, com a função swicth.
O switch é um comando de tomada de decisão. O switch pode ser comparado com o if-else, porém o primeiro não aceita expressões, apenas variáveis. O switch testa a variável e executa a declaração cujo case corresponda ao valor atual da variável. A declaração default é opcional e será executada apenas se a variável, que está sendo testada, não for igual a nenhuma das constantes. O comando break, faz com que o switch seja interrompido assim que uma das declarações seja executada. Mas ele não é essencial ao comando switch. Se após a execução da declaração não houver um break, o programa continuará executando.O comando continue pode ser visto como sendo o oposto do break. Ele só funciona dentro de um loop. Quando o comando continue é encontrado, o loop pula para a próxima iteração, sem o abandono do loop, ao contrário do que acontecia no comando break.

Alguns comentários foram feitos dentro do programa:


#include conio.h
#include stdio.h
void main()
{

int escolha=1;

// se a escolha for diferente de 5, ele continua... o que inicialmente é verdade
// pois escolha é igual a 1
while (escolha!=5)
{

printf("\n\n ----------------------- ");

printf("\n 1 - Opcao 1 ");
printf("\n 2 - Opcao 2 ");
printf("\n 3 - Opcao 3 ");
printf("\n 4 - Opcao 4 ");
printf("\n 5 - Fechar Programa ");
printf("\n\n Escolha uma opcao: ");
scanf("%d",&escolha);


// estrutura switch
switch (escolha) {

case 1:
{

// a função clrscr(); é para limpar a tela
clrscr();
printf("\n\n Opcao escolhida: 1 ");

break;
}

case 2:
{
clrscr();
printf("\n\n Opcao escolhida: 2 ");
break;
}

case 3:
{
clrscr();
printf("\n\n Opcao escolhida: 3 ");
break;
}

case 4:
{
clrscr();
printf("\n\n Opcao escolhida: 4 ");
break;
}

// opção padrão
default:
{
clrscr();

// se for escolhida a opção 5, ele pula o while utilizando continue para isso
if( escolha==5)
{
continue;
}
// caso o usuário digite um numero acima de 5, ele irá informar que nao existe essa opção
printf("\n\n Nenhuma opcao foi escolhida ");
break;
}

}

}

if( escolha==5)
printf("\n\n O Programa foi fechado");

getch();

}

quarta-feira, 23 de março de 2011

Criptografia Quântica

Criptografia Quântica

Introdução

Criptografia, a ciência da comunicação secreta, está se tornando cada vez mais importante com o crescimento das redes de computadores e transações eletrônicas. Quando informações pessoais, financeiras e militares são transferidas, tornam-se vulneráveis a técnicas de monitoramento que potencialmente podem ter conseqüências catastróficas. Estes problemas podem ser evitados através da encriptação da informação de forma que esta se torne ininteligível a todos, menos ao destinatário. Este objetivo pode ser atingido se o remetente e o destinatário possuirem uma seqüência de bits aleatória secreta, conhecida como chave, que pode ser usada para encriptação pelo remetente e decriptação pelo destinatário.

A chave é portanto um material de grande valor apesar de não conter nenhuma informação em si. Todavia, o passo inicial da distribuição de chaves precisa ser completado com alto grau de segurança de forma que nem mesmo informações parciais sejam comprometidas.

É neste ponto que entra a criptografia quântica, cuja segurança está baseada em leis físicas, ao contrário de outras formas de criptografia que são apoiadas pela matemática.

O que está errado com a criptografia clássica?

O objetivo da criptografia é transmitir informações de forma que o acesso seja restrito apenas ao destinatário pretendido. Originalmente a segurança de um criptograma dependia do segredo dos procedimentos de criptografia e decriptografia. Atualmente usamos codificadores para os quais os algoritmos de encriptar e decriptar podem ser revelados a qualquer um sem comprometer a segurança de um criptograma em particular. Nesses codificadores um conjunto de parâmetros, chamados de chave, é fornecido junto com o texto não criptografado como entrada para o algoritmo de encriptação e com o criptograma para o algoritmo de decriptação. Os algoritmos são publicamente anunciados: a segurança do criptograma depende inteiramente da segurança da chave, e esta precisa ser composta de uma seqüência aleatória de bits.

Uma vez que a chave é estabelecida, comunicações subseqüentes envolvem o envio de criptogramas através de um canal público, que é vulnerável à espionagem passiva total (por exemplo, um anúncio numa mídia de massa). Contudo para estabelecer a chave, dois usuários (que não compartilham nenhuma informação secreta inicialmente) precisam, num certo estágio, usar um canal muito seguro e confiável. Como em teoria todo canal clássico de comunicação pode sempre ser monitorado, dois usuários legítimos podem sofrer espionagem passiva sem se darem conta.

Matemáticos tentaram resolver o problema da distribuição de chaves. Nos anos 70 houve a descoberta dos sistemas de chave pública. Nestes sistemas os usuários não precisam combinar uma chave secreta antes de enviar mensagens. Eles funcionam sobre o princípio de um cofre com 2 chaves: uma pública para trancá-lo e outra privada para abrí-lo.Todos tem uma chave para trancar o cofre mas apenas um tem a chave que abre. Estes sistemas exploram o fato de que certas operações matemáticas são mais fáceis de serem computadas em um sentido do que no outro. Eles evitam o problema da distribuição de chaves mas infelizmente sua segurança depende de uma hipótese matemática não provada, como a dificuldade de fatoração de grandes inteiros (RSA, o sistema de criptografia de chave pública mais comum baseia sua segurança nisso). Isto significa que se e quando matemáticos ou cientistas da computação desenvolverem procedimentos de fatoração mais rápidos toda a privacidade de sistemas de criptografia pública pode acabar do dia para a noite.

De fato, trabalhos recentes na área da computação quântica mostram que com o auxílio destes é possivel fatorar muito mais rápido do que com computadores clássicos.


A criptografia quântica é baseada na incerteza natural do mundo quântico. Com ela você pode criar um canal de comunicação impossível de ser monitorado sem interferir na transmissão. As leis da física dão segurança a este canal: mesmo que o observador possa fazer o que quiser, mesmo que ele tenha poder computacional infinito, mesmo que P=NP.


De acordo com a mecânica quântica, partículas não existem em um lugar específico. Elas existem em vários lugares ao mesmo tempo, com probabilidades diferentes associadas a estarem em cada posição caso alguém as observe. Todavia, somente após um cientista medir a partícula é que ela colapsa para sua posição. Acontece que não se pode medir todos os aspectos (por exemplo, posição e velocidade) de uma partícula ao mesmo tempo. Se medirmos uma dessas características o simples ato da medida destrói qualquer possibilidade de medir a outra quantidade. O mundo quântico possui uma incerteza fundamental e não há maneira de evitá-la.


Esta incerteza pode ser usada para gerar uma chave secreta. Enquanto viajam, fótons vibram em alguma direção: para cima e para baixo, para a direita e para a esquerda, ou mais provavelmente em algum ângulo. A luz do sol não é polarizada: seus fótons vibram em todos os possíveis ângulos. Quando um grande número de fótons vibra na mesma direção eles estão polarizados. Filtros polarizadores permitem que apenas fótons polarizados numa mesma direção passem, os outros são bloqueados. Por exemplo, um polarizador horizontal só permite que fótons vibrando na horizontal passem por ele. Gire-o 90 graus e apenas fótons polarizados na vertical passarão.


Digamos que você tenha um pulso de fótons polarizados horizontalmente. Se eles tentarem passar por um filtro polarizado horizontalmente, todos vão passar. Gire devagar o filtro 90 graus: o número de fótons que passam vai diminuindo, até que nenhum passa mais. Isto não é intuitivo: Parece que girar o filtro apenas um pouco deveria bloquear todos os fótons, já que eles estão polarizados horizontalmente. Mas na mecânica quântica, cada partícula tem uma probabilidade de repentinamente trocar sua polarização e ficar com a mesma do filtro. Se os ângulos diferem por pouco, a probabilidade é grande. Se diferem de 90 graus, a probabilidade é zero. Se diferem de 45 graus, a probabilidade é de 50%.
A polarização pode ser medida em qualquer base: duas direções num ângulo de 90 graus. Um exemplo de base é vertical e horizontal. Outra é diagonal direita e diagonal esquerda. Se um fóton está polarizado em uma base, emedirmos nesta base descobrimos qual a sua polarização. Se medirmos na base errada obtemos um resultado aleatório. Vamos utilizar esta propriedade para gerar uma chave secreta:
Na prática, a criptografiz quântica foi demonstrada em laboratório pela IBM e outros, mas em distâncias relativamente curtas. Recentemente distâncias da ordem de 60 Km foram obtidas usando cabos de fibra óptica de alta pureza. Acima disso a taxa de erros de bit causados pelo princípio da incerteza de Heisenberg e por inpurezas microscópicas na fibra tornam o sistema inviável. Uma pesquisa foi bem sucedida na transmissão pelo ar, mas apenas em poucas dezenas de centímetros e em condições climáticas ideais. Resta ainda saber quanto o desenvolvimento tecnológico pode aumentar essas distâncias.
Aplicações práticas nos EUA desta tecnologia incluem um link dedicado ente a Casa Branca e o Pentágono em Washington e outros links entre bases militares importantes e laboratórios de pesquisa próximos.

Perguntas

1 - Em que se baseia a segurança da Criptografia Quântica?

Na incerteza natural do mundo microscópico.

2 - Ela é segura contra qualquer tipo de ataque?

Não, apenas aos ataques de monitoramento passivo. Ela nao é segura a ataques em que o espião possa inserir e remover mensagens do meio de transmissão.

3 - Por que é necessário mandar cada bit por apenas 1 fóton?

Porque caso a informação estivesse repetida em mais de um fóton poderíamos medir a polarização de cada um deles em uma base diferente, contornando a incerteza.

4 - A criptografia quântica pode ser usada em dados armazenados?

Atualmente não, pois os fótons não existem parados, mas talvez isso se torne possível quando outras partículas como elétrons forem usadas parar armazenar informação.

5 - Atualmente, qual a distância máxima que os links usados em criptografia quântica atingem?

Cerca de 60 Km.

Fonte: http://www.gta.ufrj.br/grad/01_2/cripto/index.html


Criptografia Quântica foi hackeada ?

Nem bem a criptografia quântica chegou e cientistas afirmam que já conseguiram quebrar seus segredos. A criptografia quântica se baseia nas leis da mecânica quântica e a maioria dos cientistas considerava que redes quânticas seriam 100% seguras.

"Grampo" quântico

Um grupo de pesquisadores do MIT, Estados Unidos, conseguiu espionar uma transmissão usando uma espécie de "grampo quântico", uma técnica parecida com aquela utilizada para se escutar ligações telefônicas.

O método de espionagem e quebra da segurança não é totalmente eficaz, já que foi possível decodificar apenas metade da mensagem. Mas 50% é muito para uma rede que se considerava 100% à prova de hackers. E mais, acreditava-se ser impossível espionar uma transmissão desse tipo sem ser detectado - mas não é.

Só no laboratório

Os pesquisadores admitem que sua técnica ainda não é capaz de permitir a espionagem de uma rede real. "Não é algo que atualmente possa ser utilizado para atacar um sistema comercial," diz o físico Jeffrey Shapiro.

O sistema de criptografia quântica é tido como à prova de espionagem porque qualquer um que tente interceptar a mensagem vai quebrar a polarização do fóton coletado. Isso afeta a capacidade que o receptor tem de medí-lo corretamente. A espionagem então aparece na forma de um pico na taxa de erros da transmissão.

Entrelaçamento de partículas

Shapiro e seus colegas conseguiram contornar essa dificuldade usando um princípio físico chamado entrelaçamento, que conecta duas partículas. Utilizando um aparato óptico, eles entrelaçaram a polarização do fóton transmitido com seu momento. O espião pode então medir o momento a fim de obter informação sobre a polarização, sem afetar a polarização original.

Essa técnica não é perfeita, o que responde pelo fato de que foi possível ler apenas metade da mensagem. Nas outras vezes, o próprio processo de entrelaçamento afetou a polarização do fóton e o erro apareceu. A teoria afirma que é possível construir um aparato que não destrua nem altere os fótons, mas até hoje ninguém conseguiu construir um desses.

Enviando dados via socket's

Bom, neste tópico prentendo explicar, de forma bem simples, como enviar diversos tipos de dados via socket. Os dados que eu vou citar aqui serão: arquivos e blocos de memória. Não vou comentar sobre texto pois não é esse o foco, considerando que texto é mais facil de ser tratado...

1) O QUE É STREAM?

Stream, como o próprio nome sugere, é um fluxo de dados. Esse fluxo é linear, portanto contém um início e um fim e, a partir que o pc o lê, ele "navega" entre esse fluxo, mudando sua posição nessa "linha" de dados. Existem alguns tipos específicos de streams, mas os que iremos utilizar é o TMemoryStream. Poderíamos utilizar também o TFileStream, mas como o TMemoryStream é mais genérico acho que ele está de bom tamanho para aprendizagem ;D


2) ENTENDENDO A LÓGICA DE ENVIO

Bom, antes de começar a por a mão na massa vamos tentar entender por cima COMO vai funcionar esse envio. É capaz que algumas pessoas se percam nessa explicação por ser muito abstrata, mas não pulem essa parte, mesmo que não entendam por completo, pois senão, na hora do código vocês podem se deparar com uma lógica e não entender o por quê dela.

Primeiramente, o socket não envia toda a informação de uma vez, portanto para enviar um único stream, o evento onRead será ativado diversas vezes. Mas se tudo isso não será constante, como escrever tudo num stream só?? Como saber quando ja acabou um stream e começou o outro??

Como vocês podem imaginar, será necessário declarar uma variavel global TMemoryStream para que se junte toda a informação que vem dividida num stream só. Para saber quando acaba um stream é necessário o seguinte procedimento: primeiro é enviado o TAMANHO desse stream (em bytes) e só depois se envia o stream em si. Logo, no onRead, será necessário apenas checar o tamanho do stream que ja está escrito na memória com o tamanho recebido... Usaremos também uma variável global BOOLEAN, para verificar se o socket ja está recebendo o stream ou não, justamente para saber se vai receber o tamanho dele ou ele em si...

Bom, é basicamente assim que vamos transferir dados via socket... Neste exemplo eu vou mandar uma foto do ServerSocket para o ClientSocket... Adivinhem que foto será essa... Exato, uma screenshot da tela. Esse procedimento é utilizado em remote desktop, mas o foco aqui é apenas o envio de informação...


3) BOTANDO A MÃO NA MASSA

Bom, primeiro vamos fazer o Server que vai enviar a foto, que é mais simples... No Form coloquem apenas um ServerSocket. Vamos adicionar uma variável global TMemoryStream chamada Stream, para ser utilizada no envio.

Agora temos que colocar a função que tira a foto em si... Reparem que eu vou convertê-la para jpg para ficar menor e o envio demorar menos, portanto ponham no USES "jpeg"...

Código PHP:
function GetScreenShot: TJPEGImage;
var
Desktop: HDC;
bmp: TBitmap;
begin
Result
:=TJPEGImage.Create;
bmp := TBitmap.Create;
Desktop := GetDC(0);
try
try
bmp.PixelFormat := pf32bit;
bmp.Width := Screen.Width;
bmp.Height := Screen.Height;
BitBlt(bmp.Canvas.Handle, 0, 0, bmp.Width, bmp.Height, Desktop, 0, 0, SRCCOPY);
bmp.Modified := True;
Result.Assign(bmp);
finally
ReleaseDC
(0, Desktop);
end;
except
bmp
.Free;
bmp := nil;
Result.Free;
Result:=nil;
end;
end;
**código adaptado do torry.net**

Agora temos que especificar QUANDO o server vai começar a enviar a foto né? Vamos fazê-lo enviar quando o cliente pedir pelo comando "mandafoto". Portanto temos que adicionar uma rotina de verificação no onClientRead e, se o texto recebido for "mandafoto", ele cria o Stream, salva a foto numa variavel TJpegImage, salva essa TJpegImage pro stream, envia o tamanho do stream e, finalmente, envia o stream...

Código: Selecionar tudo

Código PHP:
procedure TForm1.ServerSocket1ClientRead(Sender: TObject;
Socket: TCustomWinSocket);
var
s: string;
Stream: TMemoryStream;
jpg: TJPEGImage;
begin
s
:=Socket.ReceiveText;
if
s = 'mandafoto' then
begin
Stream
:=TMemoryStream.Create;
jpg:=TJPEGImage.Create;
jpg:=GetScreenShot;
jpg.SaveToStream(Stream);
Stream.Position:=0;
Socket.SendText(inttostr(Stream.Size) + #0);
Socket.SendStream(Stream);
end;
end;
Notem que eu usei o null-terminator (#0) ao fim do tamanho do stream apenas como um controle para o Client, pois mesmo os textos podem ir cortados por socket...

Pronto, o Server ja está pronto, agora vamos aprender a fazer o Cliente.

Criem uma nova aplicação e coloque no form um ScrollBox (na aba Additional), uma Image DENTRO desse Scrollbox, um ClientSocket e um botão. Agora declares as seguintes variáveis globais:

Código PHP:
stSize: integer;
Stream: TMemoryStream;
Receiving: boolean;
jpg: TJpegImage;
Como ja expliquei pra que elas servem ali emcima, não vou ficar me detendo aqui... Agora, vamos fazer o Botao pedir a imagem pro Server. Para isso o Cliente deve mandar o comando "mandafoto", como já foi pré-estabelecido no Server...

Código PHP:
procedure TForm1.Button1Click(Sender: TObject);
begin
ClientSocket1
.Socket.SendText('mandafoto');
end;
Agora só falta o onRead do cliente... Antes de postar o código gostaria de que o stream, para ser utilizado corretamente, sua Position deve estar 0 (pois como disse antes, a leitura do fluxo de dados vai começar do começo). Agora, já explicado como funciona o cliente, vamos ao código:

Código PHP:
procedure TForm1.ClientSocket1Read(Sender: TObject;
Socket: TCustomWinSocket);
var
s: string;
begin
s
:=Socket.ReceiveText;
if
not Receiving then
begin
if pos(#0,s) > 0 then
stSize:=strtoint(copy(s,1,pos(#0,s)-1))
else
exit;
Stream:=TMemoryStream.Create;
Receiving:=True;
delete(s,1,pos(#0,s));
end;
try
Stream.Write(s[1],length(s));
if
Stream.Size = stSize then
begin
Stream
.Position:=0;
Receiving:=False;
jpg:=TJPEGImage.Create;
jpg.LoadFromStream(Stream);
Image1.Picture.Assign(jpg);
Stream.Free;
end;
except
Stream
.Free;
end;
end;
Pronto!! Rodem os programas e testem... Qualquer dúvida postem aqui!!

PS: Lembrando que ao invés de uma imagem, poderia ser utilizado qualquer outro tipo de dados, como um arquivo, apenas utilizem Stream.LoadFromFile('ashdauhsdua.exe'); E lembrem-se que para poder abrir o arquivo é necessário liberar o stream da memória!!

Nota Fiscal Eletrônica (segunda geração)


Olá amigos desenvolvedores! Quem trabalha com NFe já deve ter sofrido ou está sofrendo com a "Segunda Geração" do projeto. A verdade é que as mudanças, apesar de complicar a vida dos programadores, tornaram o projeto mais seguro. Nesse artigo pretendo apontar quais foram estas principais mudanças.
As novas regras visam impedir a emissão de notas fiscais com erro de preenchimento ou em situação não prevista na legislação, apesar de gerar um certo transtorno para nós programadores, na questão de suporte claro.

Mudanças de acordo com o CRT (Código de Regime Tributário):

1 - Simples Nacional
2 - Simples Nacional - excesso de sublimite da receita bruta
3 - Regime Normal

Acredito que a regra que deve ter maior impacto para os usuário é a regra que exige o uso do CSOSN no caso do emissor ser optante pelo Simples Nacional (CRT=1). Os emissores do Simples Nacional (CRT=1) devem informar o CSOSN ao invés do CST:

NOTA EXPLICATIVA:
O Código de Situação da Operação no Simples Nacional - CSOSN será usado na Nota Fiscal Eletrônica exclusivamente quando o Código de Regime Tributário - CRT for igual a "1", e substituirá os códigos da Tabela B - Tributação pelo ICMS do Anexo Código de Situação Tributária - CST do Convênio s/nº de 15 de dezembro de 1970.

Quando o CRT=1, informar o Código de Situação da Operação - Simples Nacional (CSOSN)
101 - Tributada pelo Simples Nacional com permissão de crédito;
102 - Tributada pelo Simples Nacional sem permissão de crédito;
103 - Isenção do ICMS no Simples Nacional para faixa de receita bruta;
201 - Tributada pelo Simples Nacional com permissão de crédito e com cobrança do ICMS por substituição tributária;
202 - Tributada pelo Simples Nacional sem permissão de crédito e com cobrança do ICMS por substituição tributária;
203 - Isenção do ICMS no Simples Nacional para faixa de receita bruta e com cobrança do ICMS por substituição tributária;
300 - Imune;
400 - Não tributada pelo Simples Nacional;
500 - ICMS cobrado anteriormente por substituição tributária (substituído) ou por antecipação;
900 - Outros.

Exemplo de XML para CRT=1 e CSOSN = 101 (equivalente ao CST=00)


0
101
1.00
10.00

De forma geral, as novas regras podem ser lidas através da NT 2010/009 - divulga as situações de "uso indevido" do Ambiente de Autorização da NF-e e as novas regras de validação para reduzir o "uso indevido":

Alguns usuários poderão ter as suas NF-e rejeitadas quando a SEFAZ implementar as regras de validação em ambiente de produção e devem verificar se devem corrigir as suas aplicações.

Seguem abaixo algumas alterações críticas:

1. Especifica layout padrão de DANFE a ser seguido por todos os contribuintes.
2. Obrigatoriedade de inclusão do Código de Regime Tributário (CRT).
3. O DANFE (Documento Auxiliar de Nota Fiscal Eletrônica) utilizado para acompanhar a mercadoria em trânsito deve ser impresso em uma única via.
4. O emissor e o destinatário deverão armazenar a NF-e em arquivo digital pelo prazo estabelecido na legislação tributária, mesmo que fora da empresa. O arquivo deve ser apresentado quando solicitado em operações de fiscalização.
5. Após a concessão da Autorização de Uso da NF-e o emissor poderá corrigir erros em campos específicos da NF-e, por meio de Carta de Correção Eletrônica (CC-e), transmitida à administração tributária do Estado do emissor. A previsão é de que a CC-e esteja disponível ainda este ano.
6. Não será permitida a reutilização, em contingência, de número de NF-e transmitida com tipo de emissão "Normal".
7. Alterado o endereçamento dos web services, que agora são outros, para a versão 2.0.
8. Alterações no Código Fiscal de Operações e Prestações com relação às entradas de mercadorias a serem utilizadas nas prestações de serviços sujeitas ao ICMS e ao ISSQN.
9. Os contribuintes deverão também, incluir, quando for o caso, o Código de Situação da Operação no Simples Nacional (CSOSN). Este campo (campo CRT (C21) da tag enderEmit) foi adicionado na versão 2.0.
10. Obrigatoriedade de utilização da NF-e pelo critério do CNAE (Classificação Nacional de Atividades Econômicas)

Leia mais sobre o assunto das regras de validação no manual:
http://www.nfe.fazenda.gov.br/PORTAL/docs/NT2010.010_RegrasValidacao.pdf

Eclipse SDK 3.1

O Eclipse é um ambiente de desenvolvimento para múltiplas linguagens e plataformas. Era inicialmente um produto da IBM, que depois teve seu código-fonte liberado. Hoje, o desenvolvimento é coordenado por uma fundação. Tem implementações que rodam em Linux, HP-UX, AIX, Solaris, QNX, Mac OS X e Windows.

Link para download: http://www.eclipse.org/downloads/

Programando em C/C++ no Eclipse

Como todos sabem, o Eclipse é uma excelente IDE para se programar em Java (se não sabe, agora está sabendo).

Mas o Eclipse não se restringe somente ao ambiente Java. Com esta ferramenta também é possível programar em Python, C/C++ e até Cobol, bastando somente ter instalado o plugin adequado.

A maneira mais simples que encontrei de instalar o plugin C/C++ no Eclipse descrevo abaixo (nota: no momento em que escrevo, a versão mais atual do Eclipse é o ganymede):
  1. Com o Eclipse já aberto, navegue até o menu Help;
  2. Clique em Softwares Updates;
  3. Irá surgir uma Janela. Então navegue até a guia "Available Software";
  4. Em seguida, clique na setinha atrás de onde está escrito "Ganymede";
  5. Surgirão diversas opções. Selecione "C and C++ Development".
Por fim, agora é esperar o Eclipse efetuar os downloads necessários. Reinicie-o a seguir e pronto, você já está apto a desenvolver programas em C/C++.

Somente uma observação importante: é necessário ter instalado um compilador C/C++ na máquina. No Linux tem-se o gcc, no Windows pode ser o MinGW, Visual C/C++ ou qualquer outro. Fica a critério.

sábado, 5 de março de 2011

C# - Usando LINQ to SQL (o retorno)

Este artigo mostra como usar os recursos do LINQ to SQL em uma aplicação Windows Forms. Ele foi baseado no artigo de autoria de Scott Lysle.

Embora o Entity Framework tenha chegado para praticamente substituir o LINQ to SQL com muitas vantagens, o LINQ to SQL ainda pode ser considerado com uma alternativa viável para agilizar o desenvolvimento de aplicações com acesso a dados.

O objetivo do artigo é mostrar como acessar tabelas, consultas e stored procedures de um banco de dados SQL Server (o LINQ to SQL só funciona com ele) e também como realizar operações de alteração, inclusão e exclusão de dados.

Para o exemplo do artigo eu vou usar o banco de dados Northwind.mdf e a ferramenta Visual C# 2008 Express Edition.

A estrutura do banco de dados Northwind.mdf, exibindo suas tabelas, Views e Stored Procedures é exibida na figura abaixo:

Vamos criar uma aplicação Windows Forms e exibir contendo três formulários:

  • form1.cs - Onde iremos exibir as tabelas, consultas e stored procedures em um componente DataGridView;
  • form2.cs - Onde iremos incluir/alterar um cliente;
  • form3.cs - Onde iremos excluir um cliente.

01. O formulário form1.cs irá exibir o resultado das consultas às tabelas, querys e stored procedures em um controle DataGridView e deverá possuir um menu criado via controle MenuStrip conforme o leiaute abaixo:

Para cada item do menu vamos definir sub-itens conforme as figuras a seguir:

a. Consultas

b. Movimento

02. O formulário form2.cs é exibido na figura abaixo e apresenta os controles Label e TextBox para realizar a alteração/inclusão na tabela Customer:

03. O formulário form3.cs, da figura abaixo, é usado para excluir um registro da tabela Customer e possui o controle Label, TextBox e Button:

Criando o DataContext e as classes com o código LINQ to SQL

Agora vamos criar a infraestrutura usando classes onde devemos criar o código usando LINQ to SQL. Antes, devemos realizar o mapeamento objeto relacional para gerar as classes a partir das tabelas do Northwind.

No menu Project -> Add New Item , selecione o template LINQ to SQL Classes, informe o nome Northwind.dbml e clique em Add.

A seguir, arraste e solte, a partir da janela DataBase Explorer, as tabelas do Northwind para o descritor LINQ, a fim de gerar as classes com o mapeamento ORM. Devemos arrastar também as stored procedures Sales_by_Year e Ten_Most_Expensive_Products na painel de métodos do descritor, conforme a figura abaixo:

Com isso já temos todo o mapeamento objeto relacional gerado e já podemos trabalhar com as classes que representam as tabelas do nosso banco de dados.

Para isso eu poderia criar uma classe e nela definir os métodos para acessar as tabelas, consultas e stored procedures, e os métodos para realizar alteração e inclusão, mas vou fazer diferente: vou criar classes distintas para cada item. Assim, teremos as seguintes classes:

  • acessoLinqTabelas.cs

    - contém os métodos LINQ para acessar as tabelas retornando todos os dados da tabela. Irei retornar os dados para as seguintes tabelas: Customers,Employees, Orders, Categories e Products;

  • acessoLinqConsultas.cs - contém os métodos LINQ para acessar as consultas: Orders by ID, Orders and Details e Employees by ID;
  • acessoLinqStoreProcedure.cs - contém os métodos para acessar as stored procedures: Sales by Year, Ten Most Expensive Products;
  • acessoLinqCrud.cs - contém os métodos para realizar as operações de incluir, alterar e excluir registros da tabela Customers.

01. Criando a classe para acessar as tabelas

Vamos iniciar, então, criando a classe para acessar as tabelas selecionando no menu Project -> Add Class e informando o nome acessoLinqTabelas.cs;

A seguir, defina o código abaixo na classe:

using System;
using System.Collections.Generic;
using
System.Linq;
using System.Text;

namespace LinqToSQL_Cshp1
{

class acessoLinqTabelas
{
///

/// Obtem dados da tabela Customer
///
summary> obtem; <> return
}

///
/// Obtem dados da tabela
Employee
///
///

public static
System.Data.Linq.Table GetEmployeeTable()
{

NorthwindDataContext dc = new

NorthwindDataContext();
return dc.GetTable< return

}
///
/// Obtem dados da
tabela Order
///
///

public static
System.Data.Linq.Table GetOrderTable()
{

NorthwindDataContext dc = new

NorthwindDataContext();
return dc.GetTable< return

}
///
/// Obtem dados da
tabela Category
///
///

public static
System.Data.Linq.Table GetCategoryTable()
{

NorthwindDataContext dc = new

NorthwindDataContext();
return dc.GetTable< return

}
///
/// Obtem dados da
tabela Product
///
///

public static
System.Data.Linq.Table GetProductTable()
{

NorthwindDataContext dc = new

NorthwindDataContext();
return dc.GetTable< return

}
}
}

Programando threads em C#

Todo programa desenvolvido em C# possui uma thread. Esta é conhecida como thread principal. Muitos programas geralmente precisam realizar tarefas que levam um longo tempo. Se a thread principal do aplicativo for dedicada a isto, o aplicativo pode parar de responder até que a execução esteja concluída.

Para permitir que um aplicativo execute uma tarefa e continue a responder, ou para realizar várias tarefas ao mesmo tempo, podemos programar conceitos de multitarefa (multithreading).

Além de realizar processamento em segundo plano, é uma ótima maneira de melhorar o desempenho das tarefas do processador em computadores com vários processadores ou núcleos. Se um computador tem vários processadores ou vários núcleos em um único processador, ele pode executar múltiplas tarefas simultaneamente, mesmo que elas exijam tempo de processamento.

Portanto, acrescentar multitarefa em uma aplicação pode reduzir o tempo que leva para completar uma tarefa.

Criando uma thread simples

Existem várias formas de programarmos execução em segundo plano nos softwares que desenvolvemos. Uma delas é criar um método dentro da classe exclusivo para execução da tarefa em segundo plano e outro responsável pela chamada desta tarefa, como é demonstrado no código a seguir.

// C#
public class GerenciaThread
{

public void ChamarThread()
{
System.Threading.ThreadStart ts =
new System.Threading.ThreadStart(ExecutarThread);
System.Threading.Thread t =
new System.Threading.Thread(ts);
t.IsBackground = true;
t.Start();
}

private void ExecutarThread()
{
// Código a ser executado pela thread
}
}

Repare que no exemplo acima, o único método público dentro da classe ‘GerenciaThread’ é o ‘ChamarThread’. Coloquei desta forma para evitar que o método ‘ExecutarThread’ seja chamado em outros locais a não ser nesta mesma classe, e ,desta forma, permitir que o processo seja executado apenas através da thread em background.

Para iniciar o processamento em segundo plano, basta chamar o método ‘ChamarThread’.

// C#
GerenciaThread gt = new GerenciaThread();
gt.ChamarThread();

Passando parâmetros para a Thread - parte 01

Em algumas situações é necessário passar informações para a thread para serem usadas durante o processamento. Essa passagem de dados pode ser feita de várias maneiras. Uma delas é criar um construtor na classe que executa a thread permitindo um ou mais parâmetros. Ao criar a instância da classe, use este construtor e passe os parâmetros desejados.

Por exemplo, podemos executar logs de erros em threads em background. Mas para que o log seja armazenado em algum repositório, é necessário informar para a thread algumas informações como o erro ocorrido, onde ele ocorreu, etc. Usando o mesmo conceito do exemplo anterior, podemos colocar no construtor da classe ‘GerenciaThread’ os parâmetros necessários para gravação do log, como o código abaixo demonstra.

// C#
public class GerenciaLogErro
{
private Exception exception;

// Nome do projeto onde ocorreu o erro
private string strNomeProjeto;

// Nome da classe onde ocorreu o erro
private string strNomeClasse;

// Nome do método onde ocorreu o erro
private string strNomeMetodo;

public GerenciaLogErro(Exception _exception,
string _projeto,
string _classe,
string _metodo)
{
this.exception = _exception;
this.strNomeProjeto = _projeto;
this.strNomeClasse = _classe;
this.strNomeMetodo = _metodo;
}

public void ExecutarLogErro()
{
// Gravar Log no Repositório
// ou no Log de Eventos do Windows
}
}

public class LogErro
{
public void LogarErro(Exception exception,
string strNomeProjeto,
string strNomeClasse,
string strNomeMetodo)
{
GerenciaLogErro gle = new
GerenciaLogErro(exception,
strNomeProjeto,
strNomeClasse,
strNomeMetodo);

System.Threading.ThreadStart ts = new
System.Threading.ThreadStart(gle.ExecutarLogErro);
System.Threading.Thread t = new
System.Threading.Thread(ts);
t.IsBackground = true;
t.Start();
}
}

Repare que na classe ‘GerenciaLogErro’ foi criado um construtor que recebe 4 parâmetros, e esses parâmetros serão gravados no repositório para registro do Log.

A chamada para o método que executa o log pode ser feita conforme o código a seguir.

// C#
try
{
//Coloque aqui o código que deverá ser executado no método
Console.WriteLine(\"Esta é a Thread Principal\");
}

catch (Exception ex)
{
LogErro logErro = new LogErro();
logErro.LogarErro(ex,
\"ThreadPassingData\",
\"Program\", \"Main\");
}

Passando parâmetros para a Thread - parte 02

Outra forma de passar dados para a thread é criando uma classe que conterá propriedades que representarão os parâmetros que devem ser passados para a thread, como o código abaixo demonstra usando o mesmo exemplo de gerenciamento de logs.

// C#
public class DadosLog
{
public Exception Exception { get; set; }
public string StrNomeProjeto { get; set; }
public string StrNomeClasse { get; set; }
public string StrNomeMetodo { get; set; }
}

Em seguida, o método que executará o processo em segundo plano deve ter como parâmetro de entrada um object, que em seguida será convertido para o tipo DadosLog.

// C#
public void ExecutarLogErro(object _dadosLog)
{
DadosLog dadosLog = (_dadosLog as DadosLog);

// Gravar Log no Repositório ou no Log de Eventos do Windows
}

Para concluir, passamos a instância da classe DadosLog no método Start() no momento da chamada à thread. Veja:
// C#
public void LogarErro(Exception exception,
string strNomeProjeto,
string strNomeClasse,
string strNomeMetodo)
{
DadosLog dadosLog = new DadosLog()
{
Exception = exception,
StrNomeClasse = strNomeClasse,
StrNomeMetodo = strNomeMetodo,
StrNomeProjeto = strNomeProjeto
};

GerenciaLogErro gle = new GerenciaLogErro();
Thread t = new Thread(gle.ExecutarLogErro);
t.IsBackground = true;
t.Start(dadosLog);
}

Conclusão

Usar Threads é sempre vantajoso no ponto de vista de que podemos aproveitar o poder de processamento dos processadores que possuem mais de um núcleo, pois podemos programar para que cada thread tenha o seu processamento realizado por núcleos diferentes. Mas é sempre importante avaliar corretamente a utilização de threads, pois a concorrência poderá causar deadlocks e funcionamento incorreto de um procedimento.

Código fonte

Os códigos fontes podem ser baixados nos seguintes links:

A cooperação é fundamental para a segurança da internet

Para que as táticas de segurança ofensivas sejam bem-sucedidas na luta contra o cibercrime, é necessário que consumidores, pesquisadores de segurança, jornalistas, legisladores e a polícia cooperem. A colaboração de todos é fundamental na batalha contra os criminosos on-line.

A cooperação entre pesquisadores de segurança tem uma longa história. Os vírus de computador foram reconhecidos como um problema global desde o início, quando a indústria consistia, basicamente, em um punhado de pessoas que criavam ferramentas antivírus nos anos 80 e 90, predominantemente para PCs com sistema operacional Microsoft DOS.

Naquela época, o ritmo da propagação de vírus era muito diferente - eles trafegavam quase que exclusivamente via de troca de disquetes -, portanto os pesquisadores se encontravam várias vezes por ano para compartilhar coleções e descrições de vírus, normalmente em eventos de segurança. Nesse período, surgiram duas organizações: a Computer Antivirus Research Organization (CARO) e o European Institute for Computer Antivirus Research (EICAR).

A primeira tentativa de criar padrões na indústria de malware foi o CARO BASE, um banco de dados de texto que descrevia os vírus. Esse padrão, desenvolvido e mantido pela CARO, foi estabelecido de 1993 a 1994. O crescimento da internet e do e-mail em 1996 e 1997 permitiu que o malware se propagasse mais rapidamente, e isso também resultou no crescimento gradual dos números do malware. Então, os fornecedores de segurança precisavam de um intercâmbio mais rápido de informações e amostras.

Primeiro, as empresas de antivírus, que atualizavam seus produtos semanal ou mensalmente, passaram a fazê-lo diariamente e a coletar malware diariamente. Segundo, a indústria criou várias listas de e-mails de emergência. Elas permitiram que os pesquisadores dessas empresas se comunicassem durante epidemias globais. Um exemplo bem-sucedido dessa ação foi a Anti-Virus Emergency Discussion Network durante as epidemias globais criadas por W97M/Melissa (1999), VBS/LoveLetter (2000), W32/Nimda (2001) e, posteriormente, W32/Netsky, W32/Bagle e W32/Mydoom (2004).

Epidemias globais de malware por meio de worms de rede e e-mail eram comuns no período de 1999 a 2004. Quando ocorria uma epidemia, todas as empresas de segurança queriam fornecer proteção o mais rapidamente possível. A sincronização dos nomes de malware não era prioridade. Nesse estágio, testemunhamos o que provavelmente foi a primeira tentativa pública de regulamentar a indústria de antivírus.

O cenário de ameaças começou a mudar rapidamente por volta de 2003, quando o malware começou a se tornar comercial. Epidemias em grande escala de malware replicante tornaram-se raras. Em vez da autorreplicação, a própria internet proporcionou aos criadores de malware o mecanismo de entrega de que eles precisavam. Os vírus começaram a morrer como dinossauros, sendo substituídos por cavalos de Troia, pois o malware e a internet tornaram-se inseparáveis. Devido ao volume crescente de malware, o processamento automático do intercâmbio de amostras tornou-se comum.

Logo os cibercriminosos reconheceram que a internet era uma ferramenta útil para fazer dinheiro. Por isso, eles desenvolveram técnicas para se apropriarem de um número significativo de computadores para explorar as vítimas via de envio de spam, ataques de negação de serviço e outros métodos. Os criadores de malware se transformaram em controladores de redes de robôs (redes de bots ou botnets, compostas por programas maliciosos controlados remotamente, executados nas máquinas de vítimas incautas).

Grandes redes de bots, como storm e conficker, agora compreendem milhões de computadores. A rede de bots Conficker merece uma atenção especial. Essa rede de bots tem mais de cinco milhões de computadores zumbis, e os especialistas em segurança ainda discutem a que ela se propõe. Curiosamente, essa força imensa ainda não foi empregada por seus controladores. Sabemos, porém, que um esforço coordenado de fornecedores de segurança conseguiu limitar o tamanho dessa monstruosa rede maliciosa. As empresas de antivírus organizaram o Conficker Working Group e conseguiram derrubar um dos mais importantes mecanismos de comunicação incorporados no worm conficker. Isso é um ótimo exemplo de como a indústria de antivírus pode e deve cooperar quando está diante de ameaças comuns.

Hoje em dia, a maioria das empresas de segurança utiliza sistemas de robôs automatizados que inserem dados e amostras em tempo real e geram regras de proteção. Por esse motivo, a cooperação entre as empresas de segurança continua tão importante. Para sermos eficazes, precisamos também ter uma cooperação em tempo real, contando com o auxílio de robôs. Entretanto, os robôs têm dificuldades em processar informações que não estejam bem definidas e estruturadas. Por isso, para viabilizar intercâmbios de dados, as empresas de segurança uniram forças e criaram o Industry Connections Security Group (ICSG), um sistema de compartilhamento de dados com base em XML, com o apoio do Institute of Electrical and Electronics Engineers (IEEE).

Atualmente, as soluções antivírus incluem recursos para proteção contra todas as ameaças, como firewall, antispam, antiphishing, filtros de Web, controle dos pais, entre outros. Cada elemento de proteção contribui para o cenário geral capturando e transmitindo informações de segurança. Essas informações contêm dados, por exemplo, sobre quão comuns são as ameaças, sua temporização e distribuição geográfica. Esses elementos são essenciais, especialmente quando rastreamos os malfeitores em cooperação com a polícia.

As ameaças evoluem e as soluções de proteção também. Como resultado dessas evoluções, o teste comparativo tradicional de soluções antimalware com base na varredura de conjuntos de amostras não funciona mais. Esse entendimento levou à criação da Anti-Malware Testing Standards Organization (AMTSO), que publicou diretrizes para aprimoramento dos testes.

As diretrizes da AMTSO são um bom exemplo da cooperação entre vários órgãos: testadores, meio acadêmico, editores e fornecedores de segurança. Como podemos ver, a cooperação sempre foi muito valorizada pelas empresas de segurança. Sem ela, não estaríamos tão bem protegidos quanto estamos. É claro que ainda existem desafios a superar. Afinal, as empresas antimalware são concorrentes no mercado.

No entanto, o pessoal técnico que constrói e atualiza o software de segurança entende que apenas com a cooperação podemos controlar as forças criminosas na internet. A quantidade de malware criado agora é impressionante - o McAfee Labs recebe mais de 60 mil novas amostras todo dia. Cada amostra é analisada, mas a maior parte dessa análise hoje é realizada de maneira automática, e dados compartilhados dessa indústria desempenham um papel muito importante na definição da prioridade das pesquisas.

As empresas de segurança compartilham métodos sobre malware e informações sobre arquivos. Essa última é importante para assegurar baixos níveis de alarmes falsos, frequentemente chamados de falsos positivos. A qualidade de um programa antimalware está em diferenciar o malware dos arquivos legítimos. Esse trabalho é importante para dificultar o crescimento de malware.

No futuro, esses ataques serão mais sofisticados e dirigidos, como no caso do ataque Operação Aurora, no qual uma vulnerabilidade de dia zero no Microsoft Internet Explorer foi explorada para roubar informações valiosas de várias empresas dos Estados Unidos, entre elas a Google. Os atacantes da Operação Aurora utilizaram uma abordagem sofisticada - primeiro visaram a amigos e parentes daqueles que eles queriam comprometer. Em seguida, passaram para as empresas.

Muitos desses ataques provavelmente nem são percebidos - ou não chegam a ser comunicados -, mas ainda assim as empresas de segurança precisam conhecê-los para poder agir. É por isso que o compartilhamento de informações dentro e fora da indústria é tão importante. Somente reunindo os fragmentos desses quebra-cabeças podemos responder aos ataques dirigidos.

A necessidade dessa maior cooperação entre empresas de segurança e provedores de serviços de internet é fundamental. O compartilhamento de informações de segurança deve permitir que os provedores tomem providências quanto a endereços IP e sub-redes infectadas. Um dos problemas que enfrentamos é que alguns cibercriminosos acumularam dinheiro suficiente para assumir o controle de alguns provedores locais. Já vimos vários provedores (como ESTdomains13 e McColo14) serem fechados devido a suas condutas duvidosas. Infelizmente, essa tendência de investimento criminoso em provedores de serviços de Internet continuará, sem dúvida.

O que você pode fazer?

A grande pergunta com que nos deparamos é: Quem é dono da internet? São os malfeitores ou os benfeitores? Cada lado tem a convicção de que deveria estar no comando. Usuários de computador, profissionais de segurança ou administradores devem optar por compartilhar informações de inteligência com o fornecedor de segurança de sua confiança. Provedores de serviços de internet e fornecedor de segurança também precisam cooperar com esse compartilhamento. As autoridades políticas devem levar em consideração essas questões, ao elaborar leis. Mais do que nunca precisamos de uma cooperação internacional no policiamento da internet. Essa é a chave para o sucesso.

Quando a segurança da informação realmente importa?

Terminamos 2010 com uma grande demonstração do que o acesso a informação pode gerar de impacto quando cai nas mãos de alguém que entende o valor delas, principalmente se essa pessoa sabe o que fazer com elas. A grande maioria, para não dizer todos, ficou sabendo do caso que repercutiu mundialmente denominado “WikiLeaks”. O bom mocinho, para alguns, ou ladrão e espião internacional, para outros, conseguiu de maneira não muito clara, ter acesso a 250 mil registros sobre mensagens trocadas entre os membros da diplomacia americana.

Não sei se essas informações são desde 2000, se são somente do ano 2010 ou se elas chegaram até ele através de pen-drive, micro SD, DVD, ZIP ou JPEG, não sei nem se saiu armazenada em um celular com 64gb de dentro do pentágono ou se simplesmente foi encaminhado por email em um anexo dizendo “Segue a consulta que me pediu”. O estrago foi feito. Agora corram atrás do prejuízo!

Dia desses, estava em um seminário e escutei uma pessoa falando a outra - “O bem mais valioso de uma empresa hoje é a informação!” E pensei comigo - “A informação nas mãos de alguém que saiba o que fazer com ela”. A informação em si não pode ser um bem, e se for, terá valor diferente, de acordo com a pessoa e o modo que ela for utilizada.

A intenção aqui não é mostrar o valor da informação, se ela vale mais nas mãos de uns do que de outros, e sim mostrar a importância da segurança da informação. Quanto vale sua carteira de clientes? Quanto vale a composição de seus produtos? Quanto vale sua lista de fornecedores com os descontos oferecidos? E sua composição de preços? Seus e-mails, trocados em uma negociação de compra ou de venda?

Na verdade, não temos uma resposta do valor exato para nossa informação. Podemos até ter uma ideia do prejuízo que ela causaria se fosse parar nas mãos de um concorrente ou até de um ex-funcionário, ficaríamos enfurecidos. Vamos levar o caso à polícia! Isso é um roubo de informação! Nesse momento, surge outro problema: a informação não foi simplesmente roubada, e sim duplicada. Ela continua com você, mas também na mão de outro. De repente, da mesma maneira que você organizou essa informação, ou então, já está transformada com outras informações que você desconhecia, ficará praticamente impossível provar alguma coisa.

É nesse momento que paramos para pensar: minhas informações estão seguras? Posso confiar em meus colaboradores 100%? Alguém entende o valor desta informação?

Eu sei que não podemos ficar imaginando a infinidade de maneiras com que nossa informação pode ser compartilhada indevidamente. Sei também que é praticamente impossível ficar vigiando os passos de cada pessoa dentro e fora de sua empresa, mas nem por isso vamos deixar as nossas portas digitais completamente escancaradas, afinal de contas, a divulgação da informação está ao passo de um clique, ou dois, quem sabe.

Autor: Humberto A. Izabela

vulnerabilidade XSS

Ataques XSS estão se tornando um grande problema e piorarão ainda mais se as pessoas não tomarem conhecimento desse tipo de ataque e suas vulnerabilidades.

Vulnerabilidades XSS têm sido encontradas em todos os tipos de site, até mesmo no fbi.gov, Yahoo.com, ebay.com e muitos outros sites populares e importantes.

Muitos administradores de sites falham em não atentar-se para ataques XSS, porque ou eles não sabem muita coisa sobre esse tipo de ataque, ou não os vêem como um problema.

Uma vulnerabilidade XSS quando explorada por um atacante hábil, ou mesmo um iniciante, pode ser um ataque poderoso. Este texto, procura detalhar um ataque XSS e conscientizá-lo sobre o que esses ataques são, como os atacantes usam-nos e como pode prevenir-se deles.

O que é XSS?

XSS também conhecido como CSS (Cross Site Scripting, facilmente confundido com Cascading Style Sheets) é uma vulnerabilidade muito comum encontrada em aplicativos web. XSS permite ao atacante inserir códigos maliciosos nessas páginas, para que sejam executados no momento em que tais páginas forem acessadas.

O ataque permite que conteúdos (scripts) em uma zona sem privilégio seja executado com permissão de uma zona privilegiada - i.e. escalação de privilégios no cliente (web browser) executando o script.

A vulnerabilidade poderia ser:

  • Um bug do browser que sob determinadas condições permite conteúdos (scripts) de determinado nível ser executado com permissões de níveis mais altos.
  • Um erro na configuração do browser; sites não-seguros listados em zonas privilegiadas.
  • Vulnerabilidade de cross-site scripting em uma zona privilegiada.

Um cenário comum de ataque envolve dois passos:

O primeiro passo é utilizar uma vulnerabilidade Cross Site Scripting para executar scripts em zonas privilegiadas. Para completar o ataque, realizar ações maliciosas no computador utilizando controles ActiveX não-seguros.

Esse tipo de vulnerabilidade tem sido explorada para instalar silenciosamente vários malware (tais como spyware, softwares de controle remoto, worms e coisas semelhantes) em computadores enquanto navegam em páginas web maliciosas.

Há muitos tipos de ataques XSS, mencionaremos 3 dos mais utilizados.

O primeiro tipo de ataque é de "XSS URL", que significa que o XSS não está na página e apenas será executado se colocar o código malicioso na URL e enviar a URL. Falaremos mais sobre esse tipo mais à frente e sobre como usá-lo para nossa vantagem.

O segundo tipo é em campos de texto (ou senhas), onde podemos entrar com dados, que muito comumente são vulneráveis a XSS. Por exemplo, digamos que encontramos um site com opção de busca. Agora entramos com a palavra "hacker" na caixa de busca e pressionamos enter; quando a página carrega, se retorna alguma informação dizendo "Found 100 Results For hacker", você poderá ver que serão exibidos dados na página. Mas o que aconteceria se você pudesse executar um código? Não é possível executar código PHP nesse tipo de ataque, mas certamente é possível códigos HTML, javascript.

No terceiro tipo, é possível inserir dados (códigos) e eles serão armazenados no site.

Que tipo de danos isso pode causar?

Bem, se um atacante cria um link manipulado e envia-o a uma vítima e essa vítima clica em tal link, um código javascript pode ser executado para enviar os cookies da vítima para um script CGI; obviamente que um ataque desse tipo poderia causar um dano maior. Quando um atacante cria um link malicioso, ele normalmente codifica o código javascript em HEX ou algum tipo de codificação para ocultar o código malicioso.

Sites que são vulneráveis a ataques XSS rodam algum tipo de conteúdo dinâmico, que é o tipo de conteúdo que altera-se com a interação do usuário ou informação armazenada no banco de dados, tais como fóruns, email on-line e locais onde informações são enviadas.

Você pode perguntar por que um ataque XSS não pode ocorrer enquanto o usuário não está acessando determinado domínio. Isso ocorre porque quando a vítima está em um determinado site, o código malicioso é executado sob a mesma permissão de aplicações web de domínio ou endereço IP.

Encontrando vulnerabilidade à XSS

Para encontrar vulnerabilidades XSS, devemos iniciar procurando em Blogs, Fóruns, Caixas de texto para mensagens, comentários, busca, e etc; há muitas possibilidades onde podemos encontrar esse tipo de campo, no qual podemos entrar com dados.

Podemos utilizar o Google para facilitar nossa busca. Por exemplo, se digitarmos no campo de busca do Google a linha inurl:"search.php?q=" teremos como retorno um número imenso de resultados encontrados, para encontrarmos alguns alvos para o ataque.

Se você é um desenvolvedor web, pode pensar o seguinte: "Bem, meu site não armazena nenhuma informação importante (se esse é o caso) entretanto ele usa aplicações web, por que me preocuparia com ataques?"

Há uma razão simples para isso: há um meio muito fácil de encontrar e escolher um site, e "script kiddies" freqüentemente usam esse método para descobrir aplicações web vulneráveis que possam ser exploradas. A razão pela qual eles procuram aplicações web é porque são extremamente fáceis de explorar, e quando as pessoas não prestam atenção às vulnerabilidades como o XSS, elas ficam abertas aos ataques destes script kiddies.

Esses garotos usam uma ferramenta, que usamos cotidianamente, e essa ferramenta é o Google. Alguns de nós já ouvimos falar de "Google Hacking", entretanto nem todos sabem o quão fácil é encontrar sites vulneráveis utilizando o Google.

Se eu fosse um script kiddie, a primeira coisa que gostaria de fazer seria encontrar algum código vulnerável à um ataque XSS e é claro, explorá-lo.

Após uma pequena busca no Google, fui capaz de descobrir que, o Invision Power Board 1.3.1 Final é vulnerável à XSS, e é importante saber, se já não sabe disso, que o IPB é um programa de fórum web muito popular. Também consegui encontrar uma prova do Bugtraq Exploit:

[color=[IMG]http://aaa.aa/=`aaa.jpg[/IMG]]`style=background:url("javascript:document.location.replace(´http://hackerlounge.com´);") [/color]

O exploit simplesmente redireciona a vítima para um outro site. Entretanto, se alguém alterar esse exploit (o que não necessita de muita habilidade), ele poderia facilmente ser utilizado para roubar cookies.

Agora é momento em que procuraremos quantos alvos podemos encontrar na internet.

Simplesmente digitando "Powered By Invision Power Boards 1.3.1" no Google, encontramos vários sites. Este é o principal método utilizado por script kiddies para encontrar aplicações web vulneráveis, portanto, tome cuidado se seu website puder ser facilmente encontrado e atacado.

Básico do XSS

O ataque mais comum utilizado contra vulnerabilidades XSS é a execução de códigos javascript para permitir o seqüestro de sessão (roubo de cookie). Utilizando javascript também seria possível fazer coisas com contas de usuários tal como alterar detalhes de seu perfil.

O maior risco que o XSS pode trazer é a execução de códigos no computador do usuário (client side). Entretanto, isso pode ocorrer apenas se há uma vulnerabilidade no browser que o usuário utiliza, permitindo que um ataque de tal tipo tome lugar e, para prevenir isso, é essencial que mantenha seu navegador atualizado com todos os patches. Ainda assim, recomendo que utilize o Firefox, que é reconhecidamente mais seguro que o Internet Explorer.

Vamos começar a aprender agora alguma coisa dos métodos XSS utilizados atualmente e o tipo de XSS Injection mais utilizado é:

<script>alert("XSS")

 
Design by Eddy Oliveira