Sei sulla pagina 1di 11

Esse o CC50.

O Curso de Harvard, no Brasil 2012/01

Cfrg 2: Pelcgb
n fre ragerthr ngr: 19:00, frk 09/03 Graun pregrmn qr dhr frh pbqvtb r orz pbzragnqb qr sbezn dhr n shapvbanyvqnqr frwn ncneragr ncranf cryn yrvghen qbf pbzragnevbf.

Bowrgvibf. Zryube snzvyvnevmn-yb pbz nythznf shapbrf r ovoyvbgrpnf. Fr niraghene hz cbhpb ab pnzcb qn pevcgbtensvn.

Yrvghen erpbzraqnqn. Frpbrf 11 n 14 r 39 qr uggc://vasbezngvpn.ufj.hby.pbz.oe/cebtenznpnb-rz-p.ugz

qvss cfrg2.cqs unpxre2.cqs. N rqvpnb unpxre yr b grkgb qr prfne qr hz nedhvib. A rqvpnb unpxre gragn yrine ibpr cnen b ynqb arteb qn sbepn, qrfnsvnaqb-b n penpxrne fraunf qr ireqnqr.

Esse o CC50. O Curso de Harvard, no Brasil 2012/01

Pset 2: Crypto
a ser entregue at: 19:00, sex 09/03 Tenha certeza de que seu cdigo bem comentado de forma que a funcionalidade seja aparente apenas pela leitura dos comentrios.

Objetivos. Melhor familiariz-lo com algumas funes e bibliotecas. Se aventurar um pouco no campo da criptografia. Introduzi-lo, talvez um pouco cedo demais, a File I/O.

Leitura recomendada. Sees 11 a 14, 17 a 19 e 39 de http://informatica.hsw.uol.com.br/programacao-emc.htm

diff pset2.pdf hacker2.pdf. A edio hacker l o texto de Csar de um arquivo. A edio hacker tenta levar voc para o lado negro da fora, desafiando-o a crackear senhas de verdade.

Esse o CC50. O Curso de Harvard, no Brasil 2012/01

Honestidade Acadmica. Todo o trabalho feito no sentido do cumprimento das expectativas deste curso deve ser exclusivamente seu, a no ser que a colaborao seja expressamente permitida por escrito pelo instrutor do curso. A colaborao na realizao de Psets no permitida, salvo indicao contrria definida na especificao do Set. Ver ou copiar o trabalho de outro indivduo do curso ou retirar material de um livro, site ou outra fonte, mesmo em parte e apresent-lo como seu prprio constitui desonestidade acadmica, assim como mostrar ou dar a sua obra, mesmo em parte, a um outro estudante. Da mesma forma desonestidade acadmica apresentao dupla: voc no poder submeter o mesmo trabalho ou similar a este curso que voc enviou ou vai enviar para outro. Nem poder fornecer ou tornar as solues disponveis para os Psets para os indivduos que fazem ou podero fazer este curso no futuro. Voc est convidado a discutir o material do curso com os outros, a fim de melhor compreend-lo. Voc pode at discutir sobre os Psets com os colegas, mas voc no pode compartilhar o cdigo. Em outras palavras, voc poder se comunicar com os colegas em Portugus, mas voc no pode comunicar-se em, digamos, C. Em caso de dvida quanto adequao de algumas discusses, entre em contato com o instrutor. Voc pode e deve recorrer Web para obter referncias na busca de solues para os Psets, mas no por solues definitivas para os problemas. No entanto, deve-se citar (como comentrios) a origem de qualquer cdigo ou tcnica que voc descubra fora do curso. Todas as formas de desonestidade acadmica so tratadas com rigor. Licena. Copyright 2011, Gabriel Lima Guimares. O contedo utilizado pelo CC50 atribudo a David J. Malan e licenciado pela Creative Commons Atribuio-Uso no-comercial-Compartilhamento pela mesma licena 3.0 Unported License. Mais informaes no site:
http://cc50.com.br/index.php?nav=license

Esse o CC50. O Curso de Harvard, no Brasil 2012/01

Notas: Seu trabalho neste Pset ser avaliado em trs quesitos principais: Exatido. At que ponto o seu cdigo consistente com as nossas especificaes e livre de bugs? Design. At que ponto o seu cdigo bem escrito(escrito claramente, funcionando de forma eficiente, elegante, e / ou lgica)? Estilo. At que ponto o seu cdigo legvel (comentado e indentado, com nomes de variveis apropriadas)?

Esse o CC50. O Curso de Harvard, no Brasil 2012/01

I need somebody... Help! V para


http://cc50.com.br

e faa o login, se solicitado. Depois siga at a lista de discusses. Daqui em diante, considere a Lista de Discusses do CC50 o lugar para ir quando voc tiver alguma dvida ou pergunta. Alm de postar perguntas suas, voc tambm pode procurar respostas s perguntas j feitas por outros. Espera-se, claro, que voc respeite as polticas do curso de honestidade acadmica. Postagem de trechos de cdigo sobre o qual voc tiver dvidas no geralmente um problema. Mas postagem de programas inteiros, mesmo que no funcionem, definitivamente um problema! Em caso de dvida sobre se voc deve postar ou no a sua pergunta, simplesmente mande um e-mail para ajuda@cc50.com.br, especialmente se voc precisa mostrar grande parte do seu cdigo. Mas quanto mais perguntas voc fizer publicamente, mais os outros tambm se beneficiaro! No se preocupe com o que os outros pensam das suas perguntas, voc no ser julgado nem pelo Instrutor, nem pelos colegas sobre o que voc est perguntando. Certamente, no hesite em postar uma pergunta, porque voc acha que ela "burra". Ela no ! Comeando Tudo certo, aqui vamos ns! Abra o seu Terminal e crie um diretrio chamado hacker 2 dentro de cc50, e, em seguida, navegue para dentro desse diretrio. (Lembra-se como?) O seu prompt agora deve ser semelhante ao abaixo.
username@computer (~/cc50/hacker2):

Se no for, refaa os seus passos e veja se voc pode descobrir onde est o erro. Voc tambm pode executar
history

para ver os seus ltimos comandos em ordem cronolgica, se voc gostaria de fazer alguma investigao. Voc tambm pode percorrer os comandos do seu histrico a qualquer momento usando as setas do seu teclado para cima e para baixo; pressione Enter para reexecutar qualquer comando que voc gostaria. Se voc ainda no tem certeza de como corrigir, lembre-se que http://cc50.com.br/forum o seu novo amigo! Por fim copie a Makefile que veio junto com esse documento para dentro do diretrio hacker2 que voc criou. Todo o trabalho que voc fizer para este Pset deve, no fim, residir no diretrio hacker2 .

Esse o CC50. O Curso de Harvard, no Brasil 2012/01

Ave, Csar! Lembre-se do final da Semana 2, que a Cifra de Csar criptografa (embaralha de forma reversvel) mensagens "girando" cada letra k posies, passando de 'Z' para 'A', conforme necessrio. Ns utilizaremos o alfabeto padro de 26 letras ABCDEFGHIJKLMNOPQRSTUVWXYZ
http://pt.wikipedia.org/wiki/Cifra_de_C%C3%A9sar

Em outras palavras, se p um texto no criptografado, pi o igsimo caractere de p, e k a chave secreta (um nmero inteiro no negativo), ento cada letra, ci, no texto criptografado, c, computada como: ci =(pi + k) % 26 Esta frmula talvez faz com que a Cifra de Csar parea mais complicada do que , mas ela na verdade apenas uma maneira matemtica precisa e concisa de expressar o algoritmo. E cientistas da computao amam preciso e conciso. Por exemplo, suponha que a chave k (secreta) seja 13 e que o texto p seja Nao se esqueca de beber o seu Nescau. Agora criptografamos esse p com aquela k, a fim de obter o texto c, cifrado, girando cada uma das letras 13 posies:
p: Nao se esqueca de beber o seu Nescau c: Anb fr rfdhrpn qr orore b frh Arfpnh

Observe como A (a primeira letra do texto cifrado) vem 13 letras depois de N (a primeira letra do texto original). Da mesma forma n (a segunda letra do texto cifrado) est a 13 letras de distncia de a (a segunda letra do texto original). Enquanto isso, b (a terceira letra do texto cifrado) est 13 letras distante de o (a terceira letra do texto original), nesse caso (e no primeiro tambm) tivemos que passar por 'Z' e comear de novo do 'A' para chegar l. E assim por diante. Esse no o sistema criptogrfico mais seguro, com certeza, mas divertido para implementar! Alis, uma cifra de Csar com uma chave de 13 geralmente chamado ROT13:
http://pt.wikipedia.org/wiki/ROT13

No mundo real, porm, provavelmente melhor usar ROT26, que se acredita ser duas vezes mais seguro do que ROT13.1 De qualquer forma, sua prxima meta escrever, em caesar.c, um programa que criptografa mensagens usando a Cifra de Csar. Seu programa deve aceitar um argumento de linha de comando nico: um nmero inteiro no negativo, k. Se o seu programa executado sem nenhum argumento de linha de comando ou com mais de um argumento de linha de comando, o programa deve reclamar com o usurio e retornar um valor de 1 (que tende a significar um erro), atravs do comando abaixo:
1

http://www.urbandictionary.com/define.php?term=ROT26

Esse o CC50. O Curso de Harvard, no Brasil 2012/01

return 1;

Caso contrrio, seu programa deve proceder para solicitar ao usurio o nome de um arquivo de texto, que contenha algum texto, claro, e se esse arquivo no for encontrado, o seu programa deve abortar retornando 2. Se o arquivo for encontrado, o output do seu programa ser somente a primeira linha do arquivo de texto com cada caractere alfabtico "girado" k posies; caracteres no-alfabticos (assim como letras com acentos, etc) devem ser emitidos inalterados. Aps o print desse texto cifrado, seu programa deve acabar, com a funo main retornando 0. Apesar de existirem apenas 26 letras no alfabeto padro, voc no pode assumir que k seja menor ou igual a 26; seu programa deve funcionar para todos os valores inteiros no-negativos de k menores do que 231 26. Em outras palavras, voc no precisa se preocupar se o seu programa, eventualmente quebrar, se o usurio escolher um valor para k que muito grande ou quase grande demais para caber em um int. Agora, mesmo que k seja maior do que 26, caracteres alfabticos no input do seu programa devem permanecer caracteres alfabticos no output. Por exemplo, se k 27, 'A' no deve tornar-se '[' embora o valor ASCII de '[' se encontra 27 posies acima do valor ASCII de 'A'. 'A' deve tornar-se 'B', pois 27 modulo 26 1, como um cientista da computao diria. Em outras palavras, valores como k = 1 e k = 27 so efetivamente equivalentes. Seu programa deve preservar a capitalizao: letras maisculas, embora rodadas, devem permanecer letras maisculas; letras minsculas, embora rodadas, devem permanecer letras minsculas. Por onde comear? Bem, este programa tem de aceitar um argumento de linha de comando k, por isso desta vez voc vai querer declarar main com:
int main(int argc, char *argv[])

Lembre-se que argv um "array" de strings (que so tambm conhecidas como "char estrela" por razes que veremos em breve). Na verdade, string apenas um sinnimo para char *, graas Biblioteca do CC50, voc tambm poderia declarar main com:
int main(int argc, string argv[])

se voc acha que assim a sintaxe mais clara. De qualquer maneira, voc pode imaginar um array como uma linha de armrios da escola, dentro de cada um dos quais est algum valor (e talvez algumas meias). Neste caso, dentro de cada armrio se encontra uma string. Para abrir o primeiro armrio, voc pode usar uma sintaxe como argv[0], j que arrays sempre possuem o ndice 0 como primeiro ndice. Para abrir o armrio ao lado, voc pode usar sintaxe como argv[1]. E assim por diante. Claro que, se h n, armrios melhor voc parar de abrir armrios quando encontrar argv[n-1], uma vez que argv[n] no existe! (Ou isso ou ele pertence a outra pessoa, caso em que voc no deve abri-lo) E assim voc pode acessar k usando um cdigo parecido com:
string k = argv[1];

Esse o CC50. O Curso de Harvard, no Brasil 2012/01

assumindo que k esteja realmente l! Lembre-se que argc um int que igual ao nmero de strings que esto em argv, ento melhor voc verificar o valor do argc antes de abrir um armrio que possa no existir! Idealmente, argc ser 2. Por qu? Bem, lembre-se que dentro de argv[0], por padro, se encontra o nome do prprio programa. Ento argc sempre ser pelo menos 1. Mas para este programa voc quer que o usurio fornea um argumento de linha de comando k, logo argc deve ser 2. Claro, se o usurio fornece mais de um argumento de linha de comando no prompt, argc pode ser superior a 2, neste caso, hora para algumas reclamaes. Agora, s porque o usurio digita um nmero inteiro no prompt, isso no significa que o seu input ser automaticamente armazenado em um int. Ao contrrio, ele ser armazenado como uma string que s se parece com um int! E por isso voc vai precisar converter essa string para um verdadeiro int. Como voc tem sorte! A funo atoi,existe exatamente para este fim. Veja como voc pode us-la:
int k = atoi(argv[1]);

Perceba que desta vez ns declaramos k como um verdadeiro int para que voc realmente possa fazer alguma aritmtica com ele. Ah, muito melhor agora. Alis, voc pode supor que o usurio s conseguir digitar inteiros na linha de comando. Voc no tem que se preocupar se eles digitarem, por exemplo, foo, apenas para serem difceis; atoi retornar 0 nesses casos. Alis, voc precisar de um #include alm de cc50.h e stdio.h para usar atoi sem que o gcc grite com voc. Deixamos para voc descobrir qual esse arquivo! 1 Ok, ento voc tem k armazenado como um int, agora voc ter que pedir ao usurio o nome de um arquivo de texto. Para simplificar a sua vida, o seu programa no precisar ler todo o contedo do arquivo, mas somente a primeira linha (e voc pode considerar que essa linha tem no mximo, hmm, 1000 caracteres). Para abrir e ler o arquivo, voc deve primeiro pesquisar sobre File I/O (Input/Output). As sees 18 a 20 de
http://informatica.hsw.uol.com.br/programacao-em-c.htm

iro, provavelmente, te ajudar.

man

atoi

Esse o CC50. O Curso de Harvard, no Brasil 2012/01

Uma vez que voc tem tanto k quanto o texto, hora de criptografar. Lembre-se que voc pode iterar sobre todos os caracteres em uma string, imprimindo um de cada vez, com um cdigo como o abaixo:
for (int i = 0, n = strlen(p); i < n; i++) { printf("%c", p[i]); }

Em outras palavras, assim como argv um array de strings, uma string um array de caracteres. E assim voc pode usar ndices dentro de colchetes para acessar caracteres individuais em strings assim como voc pode us-los para acessar strings individuais em argv. Legal, n? claro, a impresso de cada um dos caracteres de uma string no exatamente criptografia. Bem, talvez tecnicamente, se k = 0. Mas o cdigo acima deve ajud-lo a implementar a sua Cifra de Csar! Por Csar! Alis, voc ainda precisar incluir outro arquivo (com #include) para usar strlen.1 Essa abordagem de armazenar o texto lido do arquivo em uma string primeiro e depois iterar sobre ela no , porm, a forma mais rpida e econmica de criptografar esse texto, voc pode utiliz-la, se quiser, mas se voc quiser se desafiar mais ainda, pode tentar resolver esse problema sem armazenar o texto em uma string. Para que possamos automatizar alguns testes do seu cdigo, seu programa deve se comportar de acordo com o exemplo abaixo. Assumindo que o texto em negrito o que algum usurio digitou, e que o contedo de nescau.txt :
Nao se esqueca de beber o seu Nescau username@cloud (~/cc50/hacker2): ./caesar 13 nescau.txt Anb fr rfdhrpn qr orore b frh Arfpnh

Alm de atoi,voc pode encontrar algumas funes teis documentadas em:


http://www.cs50.net/resources/cppreference.com/stdstring/

Por exemplo, isdigit soa interessante. E, quanto continuao de 'Z' para 'A', no se esquea do operador de mdulo (%). Voc tambm pode querer verificar http://asciitable.com/, que revela os cdigos ASCII para vrios caracteres, no somente os alfabticos, apenas no caso do seu programa acabar imprimindo alguns smbolos estranhos acidentalmente. Anl sqzazkgn.

man

strlen

Esse o CC50. O Curso de Harvard, no Brasil 2012/01

Senhas et cetera. Na maioria, se no em todos, os sistemas rodando UNIX ou Linux, existe um arquivo chamado /etc/passwd. Por design, esse arquivo feito para conter nomes de usurios e senhas, juntamente com outros detalhes relacionados contas. Tambm por design (ruim), este arquivo tipicamente aberto para leitura por todos. Felizmente, as senhas no so simplesmente armazenadas nele, mas so criptografados usando uma funo "one-way hash". Quando um usurio se conecta a esses sistemas, digitando um nome de usurio e uma senha, a senha criptografada com a mesma funo hash, e o resultado comparado senha criptografada armazenada dentro de /etc/passwd. Se as duas senhas embaralhadas so iguais, o usurio ganha acesso ao sistema. Se voc j esqueceu uma senha, voc pode ter visto algo como "no posso ver qual a sua senha, mas posso mud-la para voc". Provavelmente isso acontece pois uma funo one-way hash est envolvida. Apesar de as senhas em /etc/passwd sejam criptografadas, o algoritmo envolvido no muito forte. Muitas vezes pessoas com ms intenes, mediante a obteno de arquivos como este, so capazes de adivinhar (e verificar) a senha de outros usurios ou crackea-las usando fora bruta (tentando todas as senhas possveis). Somente nos ltimos anos os administradores de sistemas (em sua maioria) pararam de armazenar senhas em /etc/passwd, comeando a usar /etc/shadows, que (pelo menos deveria ser) legvel apenas pelo usurio root. Abaixo, porm, esto alguns pares de usurio:senha-cifrada de sistemas (fake) desatualizados.
pskroob:50m2tb.6jehfA dmalan:50T5DqRZxAIe2 mscott:50WZ/Wy2GdA1Y gcostanza:50NwUtF.OmQNY guest:50Bt2CexZzo7k jcaesar:500EYaB0S7wVk cpisonis:HAkzjBWeQ/Ugc bvigenere:50dxMUnMm53rg lemon:42XWroImGkEpU

Voc deve descobrir essas senhas, cada uma das quais foi criptografada com o algoritmo (ou funo) DES-based (no MD5-based) crypt de C. Especificamente, escreva, em crack.c, um programa que aceita um argumento de linha de comando nico: uma senha criptografada1 Se o seu programa for executado sem nenhum argumento de linha de comando ou com mais de um argumento de linha de comando, o programa deve reclamar e sair imediatamente, com a funo main devolvendo qualquer int diferente de 0 (significando, assim, um erro que nossos prprios testes podem detectar). Caso contrrio, seu programa deve continuar para crackear a senha dada, de preferncia o mais rpido possvel. No fim o seu programa deve imprimir a senha crackeada seguida de '\n', nada mais, nada menos, com main retornando 0. Deixamos para voc a determinao do design deste programa, mas voc deve explicar cada uma das suas decises de design, incluindo quaisquer implicaes para o desempenho e preciso, com comentrios em todo o seu cdigo. O programa deve ser projetado de tal forma que ele possa crackear todas as senhas acima, mesmo que isso possa demorar um pouco. Isto , est tudo bem se o seu cdigo demorar
1

No caso de voc testar seu cdigo com outras senhas cifradas, saiba que os argumentos de linha de comando com certos smbolos (por exemplo "?")devem ser colocados entre aspas simples ou duplas; as aspas, no fim, no vo ficar em argv.

Esse o CC50. O Curso de Harvard, no Brasil 2012/01

vrios minutos ou horas ou at mais para ser executado. O que exigimos de vocs o desempenho correto, no necessariamente ideal. Seu programa deve com certeza funcionar com outros inputs de senhas criptografadas, alm das dadas acima; hard-coding das solues para as senhas acima no aceitvel. Mas para facilitar a sua vida, podemos dizer que nenhuma dessas senhas de exemplo tem mais do que 6 caracteres (isso no quer dizer que o seu programa no precise funcionar com senhas de mais de 6 caracteres, essas so s as senhas que voc pode usar para test-lo). Voc pode restringir a sua busca tambm apenas aos caracteres lower-case e nmeros ento o seu programa no precisa prever que as senhas tenham smbolos, espaos ou caracteres upper-case. Para que possamos automatizar alguns testes do seu cdigo, seu programa deve se comportar de acordo com o abaixo; o que algum usurio digitou est em destaque em negrito.
username@computer (~/cc50/hacker2): ./crack 50Bt2CexZzo7k guest

Assuma que as senhas originais no possuam mais do que seis caracteres. Mas pensando nas senhas criptografadas, melhor dar uma olhada na pgina man de crypt, de modo que voc saiba como a funo funciona. Em particular, certifique-se de compreender o uso de um "salt" (de acordo com a pgina do manual, um salt usado para perturbar o algoritmo em uma de 4096 maneiras diferentes" mas por que isso poderia ser til?). Como voc pode ver na pgina do manual, voc provavelmente vai querer colocar
#define _XOPEN_SOURCE #include <unistd.h>

no topo do seu programa que deve ser compilado com -lcrypt (se voc usa o make para compilar o seu cdigo, esse switch ser includo automaticamente). Por design, o /etc/passwd garante a segurana das senhas com uma suposio: que ninguem tm os recursos computacionais necessrios para crackea-las. Houve um tempo em que isso pode ter sido verdade. Mas quando se trata de segurana, as suposies so perigosas. Esperamos que esse Pset te mostre como isso verdade. Devemos ainda observar que este Pset no um convite para procurar outras senhas para crackear. No confunda essas Edies Hacker com edies mal intencionadas. Esperamos, porm, que adquirindo um melhor entendimento da concepo dos sistemas de hoje, voc poder um dia construir sistemas melhores. Alm de lhe familiarizar ainda mais com C, este pset convida voc a comear a questionar designs ruins pois problemas como vulnerabilidades na segurana resultam muitas vezes desse tipo de design. Esse foi o Set de Problemas 2.