RSS

Arquivo da categoria: segurança de sistemas

the thief detector (detector de ladrão ) :-D

Post não vai ser sobre o carrinho de controle remoto com infravermelho
sim já terminei o protótipo dele já funciona, mas quero corroer a
placa fazer algo bem mais decente, invés de ficar usando breadboard.
como eu sou bem NOOB em tudo e em eletrônica este post vai demorar.

Olhe meu vídeo que você vai entender por que quero usar IR no carrinho

strikes back

Já algum tempo que comprei sensor de movimento para fazer um sistema
detector de “ladrão”, até pensei em usar um buzzer e tudo mais,
mas detector de ladrão com buzzer é muito manjado. Como eu gosto de trazer o que é
meio incomum para o blog então tive uma ideia…

Missão comunicação serial para quando for detectar o
movimento tirar uma foto da webcam e mandar e-mail com anexo a foto.
já tem soluções com o “motion” ou mesmo com opencv detectando movimentos
da webcam reconhecimento e tudo mais, mas a ideia do feito foi treinar
desenvolvimento com “arduino pro mini” em conjunto com “FTDI“…

material usado:
Arduino pro mini – $18.95 USD sparkfun (anda meio salgado o preço prefiro o diavolino )
Resistor 10k Ohm – $0.15 santa efigenia
Pir motion sensor – $9.95 USD sparkfun
Machine Pin headers – $2.00 santa efigenia (muito chato soldar isso no arduino)
FTDI Basic Breakout 5V – $12.00 USD sparkfun

vendo como fica
pronto1

seguindo a dica de
http://bildr.org/2011/06/pir_arduino/

código do arduino

int pirPin = 9; 

void setup(){
 Serial.begin(9600);
 pinMode(pirPin, INPUT);
}

void loop(){
  int pirVal = digitalRead(pirPin);


// achou movimento
  if(pirVal == LOW)
  { 
//pausa em milesegundos equivalente ao usleep do ansi C
     delay(500);
    Serial.println("1");
  }
  //sem movimento
  else
  {
    Serial.println("0");
  }

}

Lembra da nossa Missão ?
Se o arduino detectar valor com sensor de movimento
ira mandar um OUTPUT para a porta serial,nosso programa em C
irá ficar na esculta se ele julgar movimento do conjunto de
OUTPUT ele ira tirar uma SHOOT da WEBCAM e ira mandar e-mail
com anexo
a foto…

Vamos resolver o problema do E-mail,bom fazer um cliente de e-mail do zero
em C é trabalhoso e leva tempo, então vamos instalar cliente de e-mail
instalamos o “mutt

//use o gerenciador do seu OS,se for BSD use ports...
$ sudo apt-get install mutt
$ vi ~/.muttrc

set realname="seunome"
set from="exemplo@gmail.com;"
set my_user=exemplo@gmail.com
set my_pass='sua senha'
set smtp_url=smtps://$my_user:$my_pass@smtp.gmail.com
set ssl_force_tls = yes
:wq!

vamos testar

echo 'conteúdo do e-mail' | mutt -s 'assunto do e-mail' exemplo@gmail.com

e vá ver sua caixa de corrêio verificar…

como enviar nosso anexo ?

echo 'LogLog!!!' | mutt -s 'THief Get LOg' -a c/arduino/test.jpg -- exemplo@gmail.com

quer aprender mais sobre o mutt ? “man mutt

agora podemos partir para o código
não fique triste por eu ter usado o OpenCV para tirar foto da webcam

/*
contato: c00f3r@gmail.com
autor: Antonio Costa aka Cooler_
coolerlab.wordpress.com

Simples detector de ladrão usando Arduino+sensor de movimento

apt-get install libhighgui-dev  libcv
gcc -o thiefget thiefget.c  -lcv -lhighgui -lcxcore; ./thiefget

usei o OpenCV para tirar shoot da webcam pois não conheço outra API
que faça o mesmo...

só para enviar e-mail que usei programa de terceiro... parece gambi até xD

executando:
como argumento o seu dispositivo onde esta o arduino
./thiefget /dev/ttyUSB0


 */
#include <stdio.h>    
#include <stdlib.h> 
#include <string.h>   
#include <unistd.h>   
#include <termios.h>  
#include <fcntl.h> 
#include "opencv/cv.h"
#include "opencv/highgui.h"

// quantas vezes o sensor retornara 1 para mandar e-mail ?
#define MOVES 16

// numero que tolera erros
#define FAIL 16

// sempre concatene com 'B' a  taxa de transmissão ,"9600" padrão do AVR
#define BAUDRATE B9600

int serialboot(const char* serialport, int baud);
int serialread(int fd, char* buf, char until);
void webcam(const char* file);

void banner() 
{
 printf("\nFollow patern: ./PegaLadrao <SerialPort>\n"
  "Just Another geek Cool THing With ArduinO!!!\n"
  "Simple THief Get\n"
  "Coded By Cooler_\n"
  "coolerlab.wordpress.com\n"
  "\n");
}

int main(int argc, char *argv[]) 
{
 int baudrate = BAUDRATE,fd=0,counter=0,OFF=0; 
 char *buf=malloc(sizeof(char)*16);
 char *serialport=malloc(sizeof(char)*512);

  if(argc<2) 
  {
   banner();
   exit(EXIT_SUCCESS);
  }
    
  printf("Serial:%s\n",argv[1]);

//conection
  strncpy(serialport,argv[1],512);
  fd=serialboot(serialport, baudrate);

   if(fd<=0)
   {
    puts("veja se o dispositivo esta conectado!!");
    printf("%d\n",fd);
    exit(EXIT_SUCCESS);
   }
 
  while(1) 
  {
    
// tempo em milesegundos, altere como for necessário
   serialread(fd, buf, '\n');
   printf("====================\nread: %s\ncounter: %d\n===================\n",buf,counter);

// se ler "1" contador é atribuido
     if(strcmp(buf,"1")>0)
     {
      usleep(500000);
      puts("MOVEMENT ONLINE");
      puts(buf);
      counter++;
      OFF=0;
     } 
//numero de vezes que achou movimento
     if(counter==MOVES)
     {
      puts("cof cof thief in HOME");
      webcam("test.jpg");
      system("echo 'LogLog!!!' | mutt -s 'THief Get LOg' -a /home/nick/c/arduino/test.jpg -- exemplo@gmail.com");
      break;
      counter=0;
     } 
     if(!strlen(buf))
      OFF--;
     if(OFF==FAIL)
      break;
     
  }

 puts("Simple THief Get ,set to OFF");
 close(fd);
 free(buf);
 free(serialport);

 exit(EXIT_SUCCESS);    
} 

int serialread(int fd, char* buf, char until)
{
 char b[1];
 int i=0;
 do { 
  int n=read(fd, b, 1);  
  if(n==-1) 
    return -1;    
  if(!n) 
  {
   usleep(16000); 
   continue;
  }
  buf[i] = b[0]; 
  i++;
 } while(b[0]!=until);

 buf[i]=0;  

 return 0;
}

int serialboot(const char* serialport, int baud)
{
 struct termios toptions;
 int fd;

    fd = open(serialport, O_RDWR | O_NOCTTY | O_NDELAY);

    if(fd == -1)  
    {
     puts("serialboot: não foi possivel abrir a porta ");
     return -1;
    }
    
    if(tcgetattr(fd, &toptions) < 0) 
    {
     puts("serialboot: nao foi possivel pegar atributos do terminal");
     return -1;
    }
    speed_t brate = baud; 
    cfsetispeed(&toptions, brate);
    cfsetospeed(&toptions, brate);
   // para default recv com termios.h
    // 8N1
    toptions.c_cflag &= ~PARENB;
    toptions.c_cflag &= ~CSTOPB;
    toptions.c_cflag &= ~CSIZE;
    toptions.c_cflag |= CS8;
    // no flow control
    toptions.c_cflag &= ~CRTSCTS;
    toptions.c_cflag |= CREAD | CLOCAL;  // turn on READ & ignore ctrl lines
    toptions.c_iflag &= ~(IXON | IXOFF | IXANY); // turn off s/w flow ctrl
    toptions.c_lflag &= ~(ICANON | ECHO | ECHOE | ISIG); // make raw
    toptions.c_oflag &= ~OPOST; // make raw

    // olhe http://unixwiz.net/techtips/termios-vmin-vtime.html
    toptions.c_cc[VMIN]  = 0;
    toptions.c_cc[VTIME] = 20;
    
    if(tcsetattr(fd, TCSANOW, &toptions) < 0) 
    {
     puts("serialboot: nao foi possivel adicionar atributos no term erro 1");
     return -1;
    }

 return fd;
}

/*tira foto usando opencv
  não queria usar opencv, mas unica API que ja tinha
 usado com a webcam...
*/
void webcam(const char* file)
{
 CvCapture *capture = cvCreateCameraCapture(0);
   if(capture==NULL)
    puts( "nao he possivel pegar foto!\n");

  IplImage* frame = cvQueryFrame( capture );
   if(!frame)
    puts( "erro na foto!\n");

  int imageParams[3] = {CV_IMWRITE_JPEG_QUALITY, 100, 0};
  cvSaveImage(file , frame,imageParams);
  cvReleaseCapture( &capture );
}

veja o e-mail que chegou quando cheguei proximo do sensor
e-mailcooler

muito divertido…

bom é isso ai,
escrevi o código meio que na correria mas acho
que deu para explanar a ideia…
fique avontade para melhorar o código 😉

 
8 Comentários

Publicado por em dezembro 4, 2011 em arduino, hacking, Linguagem C, segurança de sistemas

 

Race Conditions

O que é ?

Em palavras simples “Race Condition” é rotulado quando o código é uma condição não atômica ou seja thread-unsafe e não reentrante, uma condição de corrida é um comportamento anômalo causado pela dependência inesperada no tempo relativo de eventos, Race Condition pode ter vários contextos tais como em “threads”, “Time of check, time of use race condition”,”switch” em adição quando o desenvolvedor não trata todos os dados de entrada “stdin”, algum desses dados pode comprometer a integridade do sistema seja abrindo algum arquivo como “/etc/shadow“, fazendo disclosure de outros arquivos que você não gostaria, sim pode ter relação direta com a falha LFD(Local File Disclosure) na maioria dos casos comuns, mas condições de corrida estão além, imagina você manipular um arquivo temporário e criar um link simbólico para o local do qual gostaria, vou tentar passar um conceito básico neste post.
road_rash_-_1992_-_electronic_arts1
Vamos a um exemplo, tudo começa com uma má prática de permissão
ou acesso no file system com uso sem tratamento dos dados dos argumentos
passados para os syscalls exemplo open(),read(),chmod(),symlink(),unlink(),
lchown(),chown()
entre outras funções que envolve manipulação de permissões e
arquivos , “háha mais eu uso fopen()” rode um “strace” no executável do
seu programa que você terá uma surpresa o syscall open() estará la.
linguagens como Java,Perl,Ruby dependem da libC para rodar em unix
like fora as syscalls então não são imunes ao problema , irei mostrar
um ponto empírico;

cooler@lisperian:/etc$ LD_TRACE_LOADED_OBJECTS=1 jvm
linux-gate.so.1 => (0x0022a000)
libpthread.so.0 => /lib/i386-linux-gnu/libpthread.so.0 (0x0093f000)
libdl.so.2 => /lib/i386-linux-gnu/libdl.so.2 (0x00e12000)
libutil.so.1 => /lib/i386-linux-gnu/libutil.so.1 (0x00183000)
libssl.so.1.0.0 => /lib/i386-linux-gnu/libssl.so.1.0.0 (0x0018a000)
libcrypto.so.1.0.0 => /lib/i386-linux-gnu/libcrypto.so.1.0.0 (0x0031a000)
libz.so.1 => /lib/i386-linux-gnu/libz.so.1 (0x00110000)
libm.so.6 => /lib/i386-linux-gnu/libm.so.6 (0x00c15000)
libc.so.6 => /lib/i386-linux-gnu/libc.so.6 (0x00641000) --> aqui libC
/lib/ld-linux.so.2 (0x00b20000)

Relaxe normal a “jvm” do java depender de C ,poh DMR morreu ninguém falo nada
se fosse o James Gosling! hehehe…

Ao falar de “Race Conditions” no contexto de “threads”, temos duas formas condições não atômicas
e atômicas ,condições atômicas não são vulneráveis , mas as condições não atômicas
são vulneráveis são thread-unsafe e não reentrantes.

*O que é “não reentrante” ?

Não reentrante refere-se a qualidade duma subrotina de ser executada concorrentemente
de forma insegura, é exatamente o antônimo de reentrante que seria uma subrotina segura.

Ex:


 int madruga = 2;

 int foo()
 {
   madruga += 8;
   return madruga;
 }

 int gamma()
 {
   return ( ( foo() -4 ) << 2) ;
 }

Se duas thread executar uma função seja foo() ou gamma()
vai dar algum bug com atropelamento da variável madruga
dando um resultado inesperado…

* O que é Thread-unsafe ?

A thread fica insegura quando os dados de forma concorrentemente
são alterados por usar uma variável global ou por não usar Lock por
mutex , quando usamos fork() não precisamos nos preocupar, mas ao usar
pthread por exemplo deve-se ter controle seja com mutex ou com semáfaros.

Ex

// gcc -o code code.c -lpthread
#include <stdio.h>
#include <malloc.h>
#include <pthread.h>

int y=1;

void *foo(void * sum)
{
 y+=*(int *)sum;
 printf(" result: %d \n",y);
}

int main()
{
 int x=0,num_thread=20;
 void *pointer=&y;

 pthread_t * threads;
 threads = (pthread_t *) malloc(num_thread * sizeof (pthread_t));

  for(x = 0; x < num_thread; x++)
   if(pthread_create (&threads[x], NULL, foo, pointer) != 0)
    error ("pthread_create");

  for(x = 0; x < num_thread; x++)
   pthread_join (threads[x], NULL);

 free(threads);
 return 0;
}

veja que este código é executado sem nenhum controle dos dados
ficam de acordo com o acaso de uma entropia da concorrência das
threads…

vamos passar o valgrind usando a tool helgrind para analisar o programa

cooler@lisperian:~/race_condition$ valgrind --tool=helgrind ./thread
==4543== Helgrind, a thread error detector
==4543== Copyright (C) 2007-2010, and GNU GPL'd, by OpenWorks LLP et al.
==4543== Using Valgrind-3.6.1-Debian and LibVEX; rerun with -h for copyright info
==4543== Command: ./thread
==4543==
resultado 2
==4543== Thread #3 was created
==4543== at 0x413A0B8: clone (clone.S:111)
==4543==
==4543== Thread #2 was created
==4543== at 0x413A0B8: clone (clone.S:111)
==4543==
==4543== Possible data race during read of size 4 at 0x804a028 by thread #3
==4543== at 0x804855D: foo (in /home/cooler/info_leak/race_condition/thread)
==4543== by 0x4028F62: mythread_wrapper (hg_intercepts.c:221)
==4543== by 0x4052D30: start_thread (pthread_create.c:304)
==4543== by 0x413A0CD: clone (clone.S:130)
==4543== This conflicts with a previous write of size 4 by thread #2
==4543== at 0x8048566: foo (in /home/cooler/info_leak/race_condition/thread)
==4543== by 0x4028F62: mythread_wrapper (hg_intercepts.c:221)
==4543== by 0x4052D30: start_thread (pthread_create.c:304)
==4543== by 0x413A0CD: clone (clone.S:130)
==4543==
==4543== Possible data race during write of size 4 at 0x804a028 by thread #3
==4543== at 0x8048566: foo (in /home/cooler/info_leak/race_condition/thread)
==4543== by 0x4028F62: mythread_wrapper (hg_intercepts.c:221)
==4543== by 0x4052D30: start_thread (pthread_create.c:304)
==4543== by 0x413A0CD: clone (clone.S:130)
==4543== This conflicts with a previous write of size 4 by thread #2
==4543== at 0x8048566: foo (in /home/cooler/info_leak/race_condition/thread)
==4543== by 0x4028F62: mythread_wrapper (hg_intercepts.c:221)
==4543== by 0x4052D30: start_thread (pthread_create.c:304)
==4543== by 0x413A0CD: clone (clone.S:130)
==4543==
resultado 4
resultado 8
resultado 16
resultado 32
resultado 64
resultado 128
resultado 256
resultado 512
resultado 1024
resultado 2048
resultado 4096
resultado 8192
resultado 16384
resultado 32768
resultado 65536
resultado 131072
resultado 262144
resultado 524288
resultado 1048576
==4543==
==4543== For counts of detected and suppressed errors, rerun with: -v
==4543== Use --history-level=approx or =none to gain increased speed, at
==4543== the cost of reduced accuracy of conflicting-access information
==4543== ERROR SUMMARY: 38 errors from 2 contexts (suppressed: 715 from 32)

O próprio valgrind já disse tudo …

Quanto ao fopen(),open() fica uma dica de como fazer da forma segura:

https://www.securecoding.cert.org/confluence/display/seccode/FIO03-C.+Do+not+make+assumptions+about+fopen%28%29+and+file+creation

Lembrando sempre de validar close(),fclose() também…

https://www.securecoding.cert.org/confluence/display/seccode/FIO22-C.+Close+files+before+spawning+processes

 

* Veja alguns exploits

-Famoso XPL que se aproveita de um race condition “h00lyshit”

-Race condition no bzexe pode comprometer integridade de um sistema veja

e muitos outros…

Nos casos mais comuns é se aproveitar de um arquivo aberto para usar “symlink()”
para dar disclosure de um “/etc/shadow” por exemplo, muitos programadores cometem erros
em permissões ou em usar “open()”, a dica em arquivos é usar “flock()” .

Um obrigado ao meu brother “sigsegv“,que está presente no servidor irc.freenode.net
canal #c-br, Valeu pela dicas de race condition sigsegv 😉

 
1 comentário

Publicado por em novembro 10, 2011 em hacking, Linguagem C, segurança de sistemas

 

C pitfalls

pitfall
Pitfall não é o GaMe HeHeHe 🙂

Quando falamos em “Pitfall“, falamos de uma analogia a armadilhas da
programação ou seja buracos , que quando se cai fica ruim de subir sem ajuda de
alguém , onde um programador iniciante pode errar e não conseguir ver onde está o erro.

Primeira dica use o argumento do GCC “-Wall” e “-Wextra“, vai te ajudar a ilustrar os erros mais comuns.

Segunda *Ler manuais para entender os protótipos isso ajuda
a entender melhor as funções, exemplo “man s snprintf”

Trap dos Sinais

*bom isso “==” é diferente disso “=”

“=” você usa para atribuição “x=2″,”if((Y=a+b)>X)”
“==” você usa para comparar se um valor for igual ao outro “if(x==y)”,”x=(a==b)?5:10;”

*isso “!=” é diferente disso ‘=!’
“!=” sinal de diferente para fazer comparação “if(x!=y)”
“=!” você seta uma var para NOT,if(x=(!y))

*confundir ponteiros com operador aritmético de produto “*”
invés de fazer x=2**pointer;
faça x=2*(*pointer);
isso evita comentários indesejados caso aja operador de divisão “/”

*esquecer de botar “;” no final de cada linha é um erro comum e fácil
de detectar

*setar errado variáveis na declaração pode dar dor de cabeça
invés de fazer “int x=3,y,z=1,c=314;”
faça “int x=3,z=1,c=314” e “int y” ou “int x,z,c,y” depois setar valores…
Exemplo comum de trap em chars

char letra = 'A';             // certo 
char letra = "A";             // errado   
const char * word = "A";     // certo
const char * word = 'A';     // errado

Problemas de Casting

*Erros de “Casting” tentar armazenar uma variável float
em Int sem converter ou Double invés de float…

5 exemplos de casting

//1
  int index = 1;
  float var = 0.0;
  index = (int)var;
//2
  char c = ’A’;   
  int x = (int)c;
//3
  int x;
//printando de "A" até "Z"
  for(x=97; x<=122; x++)
   printf(" %c ", (char)x);
//4
int x=7, y=5;
float z;
z = (float)x/(float)y;  
//5
int x = 13;
printf("x/2 is %f", (float)x / 2);

Problemas em Leituras de variáveis “STDIN”

Maioria do pessoal que começa em C comete este erro veja só
o exemplo do “scanf()”

 int x;
 char *palavra=malloc(8*sizeof(char));

 scanf("%d",&x);
// quando é string não usa "&"
 scanf("%s",&palavra);
 puts(palavra);
 printf("%d \n",x);
 free(palavra);

A o uso do operador “&” no “scanf()” quando trabalhamos com string
nos trás erro, outro problema comum é o bug do “newline”, ao teclarmos
“enter” no final de um “STDIN” no final da string fica “\n” alguns
casos ocorre um “jump” pelo código e alguns outros erros estranhos,
alguns usam “getchar()” para evitar, outros criam uma função ou macro

eu costumo usar ReadString, vou mostrar minha
macro e uma função do meu amigo m0nad

// minha macro para remover o '\n'
#define ReadString(a) fgets(a,sizeof(a),stdin),a[strlen(a)-1] = '\0'; 
 
//func fo m0nad
void
chomp (char * str)
{
  while (*str) {
    if (*str == '\n' || *str == '\r') {
      *str = 0;
      return;
    }
    str++;
  }
}

// ex de uso dump_line(stdin);
void dump_line( FILE * fp )
{
  int ch;
  while( (ch = fgetc(fp)) != EOF && ch != '\n' )
}

Sempre bom validar entradas “STDIN” para
ter um controle maior e melhorar segurança do seu programa, procurar usar
strncpy() invés de strcpy(), strncmp(),snprintf() e outras funções mais seguras, principalmente ao nidar com “argv” vide ataques de Buffer Overflow e format string.

*Pthread e o Lock com Mutex
Parece ser dica para ganhar desempenho , mais muitos acabam ganhando
dor de cabeça em não implementar , bom invés de

 pthread_mutex_lock(&count_lock); 
   temp = sqrt(x); 
   fd = open(fname, O_CREAT | O_RDWR, 0666); 
   count++; 
   *bufp = (char *)malloc(256); 
 pthread_mutex_unlock(&count_lock); 

faça

  temp = sqrt(x); 
  fd = open(fname, O_CREAT | O_RDWR, 0666); 
  pthread_mutex_lock(&count_lock); 
   count++; 
  pthread_mutex_unlock(&count_lock); 
  *bufp = (char *)malloc(256); 

trancar apenas o que for necessário, quando falamos de mutex

*Problemas na HEAP

Para evitar *Memory leaks sempre que usar a HEAP usar free(),
com “malloc()” dê “free(var)” para dar clear na HEAP, para verificar
se tem memory leaks no seu código use o valgrind.
Outra dica é usar alloca() já que é baseada em Stack invés de Heap,
mas tem um certo problema para depuração…
DMR ,Linus coment about alloca()

exemplo de uso do free()

#include <malloc.h>
#include <unistd.h>

int main()
{
 char *x=malloc(3*sizeof(char));

 x[0]='o';
 x[1]='l';
 x[2]='a';

 write(1,x,3);
 write(1,"\n",2);

 free(x);

 return 0;
}

Ao tirar o “free()” e passar o valgrind veja o que se passa

cooler@lisperian:~/c/pitfall$ valgrind ./a
==12647== Memcheck, a memory error detector
==12647== Copyright (C) 2002-2010, and GNU GPL'd, by Julian Seward et al.
==12647== Using Valgrind-3.6.1-Debian and LibVEX; rerun with -h for copyright info
==12647== Command: ./a
==12647==
ola
==12647==
==12647== HEAP SUMMARY:
==12647== in use at exit: 3 bytes in 1 blocks
==12647== total heap usage: 1 allocs, 0 frees, 3 bytes allocated
==12647==
==12647== LEAK SUMMARY:
==12647== definitely lost: 3 bytes in 1 blocks
==12647== indirectly lost: 0 bytes in 0 blocks
==12647== possibly lost: 0 bytes in 0 blocks
==12647== still reachable: 0 bytes in 0 blocks
==12647== suppressed: 0 bytes in 0 blocks
==12647== Rerun with --leak-check=full to see details of leaked memory
==12647==
==12647== For counts of detected and suppressed errors, rerun with: -v
==12647== ERROR SUMMARY: 0 errors from 0 contexts (suppressed: 11 from 6)

Veja que foi alocado e nada foi liberado na memória , use “free()”
caso não esteja convencido leia este paper da phrack clicando AQUI

O poderoso GDB

Quando você vê que nem você e nem seus amigos programadores acham o erro
então é hora de apelar para o GDB, sugestão para aprender usar GDB, paper
do mestre stallman

gnu gdb book

No desespero irc.freenode.net
canais #gdb,#c-br,#asm

espero ter ajudado 😉

 
2 Comentários

Publicado por em outubro 19, 2011 em Linguagem C, segurança de sistemas