Pular para o conteúdo principal

Outro dia encontrei um programa que me permitiu selecionar a partir de um conjunto de consultas pré-embaladas e depois me comuniquei com um servidor para recuperar a resposta à consulta selecionada. Comecei a me perguntar quando percebi que o programa nunca pedia uma senha para autenticação com o servidor. Acontece que a senha estava embutida no programa. O autor explicou que estava tudo bem porque 1) era um arquivo binário para que ninguém pudesse lê-lo e 2) se pudessem lê-lo, não conseguiriam encontrar a cadeia de senhas.

Nenhuma destas razões é válida e eu gostaria de usar este posto para demonstrar isso. Meu programa de exemplo apenas escreve a "senha" no terminal, mas a única diferença entre ela e um programa de produção real é o número de cordas que um usuário malicioso teria que pesquisar.

#include <stdio.h>
#include <string.h>

main ()
{
char password [9] = {"secret"};

printf ("This is the password: %sn", password);

}
Figura 1 - Programa básico com senha embutida

Quando executado, ele exibe

x1
Esta é a senha: segredo
pronto 14:12:16
Figura 2 - Execução do programa básico

Para exibir as strings no módulo do programa, nosso usuário malicioso pode usar o comando strings do >system>gnu_library>bin directory. O -n5 limita a saída para strings de 5 caracteres ou mais. Eu trunquei a saída (. . . .) para encurtar a exibição, mas você pode ver que a senha é uma das primeiras strings exibidas. Ter a senha próxima a palavras-chave como "login" ou "password" ou a um ID de usuário identificável como "admin", "root" ou "sql" torna a busca mais fácil.

>system>gnu_library>bin>strings -n5 x1.pm
bind, Release 17.1.beta.be
phx_vos#
Noah_Davids.CAC
Pré-lançamento
Esta é a senha: %s
secreto
s$start_c_program
_preensão_cleanup
sair
. . . . .
Figura 3 - Usando o comando GNU strings para encontrar todas as strings com mais de 4 caracteres no módulo do programa

Se o comando strings não estiver disponível, nosso usuário malicioso pode simplesmente exibir o módulo do programa. Suspeito que todos nós tenhamos feito isto por acidente e embora não seja bonito, ele exibirá a senha. Eu trunquei novamente a saída e novamente você pode ver a senha.

d x1.pm

%phx_vos#m16_mas>SysAdmin>Noah_Davids>x1.pm 11-01-13 14:13:59 mst

`00`01`00`1Abind, Release 17.1.beta.be`00`00`00`00`00`00`00`04ctp
`00`00`00`00`0
+`00`00`00`00`00`00`00`00`00`00`00`00`00`00`00`00`00`00`00`00`00`00`00`0
0phx_vos
+#`00`00`00`00`00`00`00`00`00`00`00`00`00`00`00`00`00`00`00`00`00`00`00`
00`00Noa
. . . .
+`00`00`00`00`00`00`00`00`00`00`00`00`00`00`00`00`00`00`00`00`00`00`00`C
D'`8B`C0
+`00`00`00`00 Esta é a senha: %s
`00`00`00`00`00`00`00secret`00`00`00`00`00`00`00`04`B0`00`00`00`00`01`00
`00`00,`
+`00`00`04`00`00`00`[email protected]`00`FF`F8`FF`FE`00`04main`00`00`83`EC`2C`C7D$$`00
. . . .
Figura 4 - Exibição do módulo do programa para encontrar a senha

Há várias alternativas para incorporar a senha no programa.

A senha pode ser colocada em um arquivo e o programa pode ler o arquivo. Somente as pessoas com "necessidade de correr" têm acesso lido ao arquivo e todos os outros têm acesso nulo. É claro que "necessidade de executar" pode não se equiparar a "necessidade de conhecer a senha". Além disso, há sempre o perigo de alguém mudar erroneamente o acesso.

Uma alternativa é manter a seqüência de senhas no programa e apenas limitar o acesso ao programa. Esta solução também sofre com o problema "é fácil mudar uma lista de acesso". Se o programa for mantido no mesmo diretório que outros programas que podem ser executados por qualquer pessoa, a probabilidade de uma mudança na lista de acesso aumenta.

Finalmente, você pode manter a senha no módulo do programa, mas de alguma forma ofuscar a corda. O programa a seguir mostra uma maneira simples de fazer isto.

#include <stdio.h>
#include <string.h> 

main ()
{
char obfuscate [9] = {0x0c, 0x81, 0xe2, 0x94, 0xe6, 0x9c};
char key [9] = {127, 228, 129, 230, 131, 232, 133, 234, 135};
char password [9];
int i;

for (i = 0; i < strlen (obfuscate); i++)
    password [i] = obfuscate [i] ^ key [i];
password [i] = 0x0;
printf ("This is the password: %sn", password);
}
Figura 5 - Programa com cadeia de senhas ofuscadas

Como você pode ver tudo o que faz é pegar os caracteres ofuscados e XOR com outro conjunto de caracteres-chave para criar a senha. A execução do programa produz a mesma saída que o primeiro programa.

x2
Esta é a senha: segredo
pronto 14:12:51
Figura 6 - Execução de programa ofuscado

Mas uma busca por cordas não mostra nada que se pareça com a senha

>system>gnu_library>bin>strings -n5 x1.pm
bind, Release 17.1.beta.be
phx_vos#
Noah_Davids.CAC
Pré-lançamento
Esta é a senha: %s
s$start_c_program
_preensão_cleanup
sair
. . . .
Figura 7 - O comando strings não mostra mais a senha

E enquanto exibe o arquivo mostrará os caracteres da senha ofuscada e os caracteres-chave que você tem que saber exatamente onde procurá-los e também como eles são combinados para criar a senha.

d x2.pm

%phx_vos#m16_mas>SysAdmin>Noah_Davids>x2.pm 11-01-13 14:15:27 mst

. . . .
+`00`00`00`00`00`00`00`00`00`00`00`00`00`00`00`00`00`00`00`00`00`CD'`8B`
C0`00`0
+0`00`00 Esta é a senha: %s

`00`00`00`00`00`00`00`0C`81`E2`94`E6`9C`00`00`00`00`00`00`00`00`00`00`7F
`E4`81`
+E6`83`E8`85`EA`87`00`00`00`00`04`B0`00`00`00`00`01`00`00`00`00`00`00`0
4`01`B0
+`00`[email protected]`00`FF`F0`00`08`FF`FE`00`04main`00`00`83`EC`89$X`89t$T`89|$P`C
7D$L`00
Figura 8 - O módulo do programa de exibição não mostra mais a senha reconhecível

Esta ainda não é uma solução perfeita, já que o módulo do programa pode ser desmontado para descobrir como a senha é gerada. A desmontagem do programa ainda requer muito mais sofisticação do que apenas a exibição do módulo do programa.

Sou de duas mentes sobre colocar a cadeia de senhas ofuscadas em um arquivo e depois proteger o arquivo através de uma lista de acesso. Por um lado, se a senha precisar ser mudada, esta é uma solução muito melhor do que incorporar a cadeia de senhas ofuscada no programa. Por outro lado, suspeito que mesmo que haja outras opções de configuração no arquivo, colocar a cadeia de caracteres no arquivo dará ao nosso usuário malicioso menos cadeias de senhas potenciais para investigar. É claro que ele ainda precisará obter acesso ao arquivo e então terá que descobrir a técnica e a chave de ofuscação.

Um último ponto, como eu gerei os caracteres da senha ofuscada? O bom da operação XOR é que ((A XOR B) XOR B) é igual a A, então eu apenas escrevi um pequeno programa para pegar a senha original XOR os caracteres com minha chave e imprimir o resultado.

#include <stdio.h>
#include <string.h>

main ()
{
char password [9];
char key [9] = {127, 228, 129, 230, 131, 232, 133, 234, 135};
char newPW [9];
int i;

strcpy (password, "secret");
for (i = 0; i < strlen (password); i++)
    {
    newPW [i] = password [i] ^ key [i];
    printf ("%xn", newPW [i]);
    }
}
Figura 9 - Programa para gerar senha ofuscada

© 2020 Stratus Technologies.