Что такое Hash Query? Если коротко, то это интерпретатор (или компилятор, если угодно) декларативного языка запросов на вычисление криптографических хэшей для строк и файлов. Hash Query умеет:
Кроме того есть:
Поддерживается следующие типы хэшей:
Использование
hq [OPTION] ...Доступные опции:
-f [ --file ] <путь> — Полный путь к файлу c запросами на языке Hash Query
-q [ --query ] <текст> — Текст запроса на языке Hash Query
-v [ --validate ] — Проверить синтаксис запроса. Не запускать никаких действий
-t [ --time ] — Показывать время вычисления хэша (по умолчанию отключено)
-l [ --lower ] — Выводить хэш в нижнем регистре
-? [ --help ] — Показать помощь
Этот язык представляет собой простой декларативный LINQ (Language Integrated Queries) или SQL подобный язык. Целью создания языка было желание предоставить единый, унифицированный интерфейс для работы с криптографическими хэшами строк и файлов с некоторыми дополнительными плюшками вроде восстановления строк по хэшам, поиск файлов по хэшам и пр.
Все задания на работу с хэшами в языке представляют собой предложения разделенные точкой с запятой «;». Они могут передаваться компилятору или через командную строку (опция -q) или быть записанными в простом текстовом файле, который потом скармливается компилятору (опция -f). В файле может быть произвольное количество запросов, но не более 10 тыс. (по соображениям производительности).
Пробельные символы в запросах (переводы строк, табуляторы и пр.) не учитываются, за исключением тех, что находятся собственно в данных (строках в кавычках или апострофах).
Все запросы имеют вид:
for … do …;
После for и do идут инструкции специфичные для каждой из категорий запроса (см. далее).
Точка с запятой в конце запроса обязательна, даже в случае единичного запроса.
В инструкциях могут встречаться строки определяемые пользователем (пути к файлам, каталогам, значения хэшей, собственно строки для вычисления по ним хэша). Строка должна быть как в апострофах (одиночных кавычках), так и в обычных кавычках (двойных кавычках). В запросах передаваемых через командную строку должны использоваться апострофы (понятно почему), в запросах из файлов можно использовать любые кавычки.
В инструкциях после for, но до do могут встречаться подвыражения let и where не являющиеся обязательными.
Подвыражение let не является обязательным и может быть опущено. Также, могут быть опущены отдельные части выражения.
Подвыражение let содержит список инструкций с разделителем запятой идущих после ключевого слова let, порядок инструкций не имеет значения. Инструкция имеет следующий вид:
<переменная>.<имя атрибута> = <значение атрибута>Переменная — это любая последовательность латинских букв и цифр, но начинаться она должна обязательно с буквы. Переменная должна быть задано до let.
Имя атрибута является одним из зарезервированных имен.
Значением атрибута является либо строка (в апострофах или кавычках), либо целое число.
Пример:
let s.md5 = '202CB962AC59075B964B07152D234B70', s.min = 3
Подвыражение where используется для задания условий, например для фильтрации файлов по некоторым признакам.
where cостоит из выражений вида:
<переменная>.<имя атрибута> <условный оператор> <значение>
идущих после ключевого слова where и соединенных операторами конъюнкции (логическое И) — and и дизъюнкции (логическое ИЛИ) — or, или другими словами после ключевого слова where должно быть булево выражение.
Переменная — это любая последовательность латинских букв и цифр, но начинаться она должна обязательно с буквы. Переменная должна быть задано до where.
Условный оператор — это один из следующий операторов:
== (равно)!= (не равно)> (больше)< (меньше)>= (больше или равно)<= (меньше или равно)~ (соответствует регулярному выражению)!~ (не соответствует регулярному выражению)Для группировки частей выражения (изменения порядка выполнения условных операторов) могут быть использованы круглые скобки.
Пример:
where (f.md5 == '202CB962AC59075B964B07152D234B70' and f.limit == 100) or (f.offset == 10 and f.md4 == 'C58CDA49F00748A3BC0FCFA511D516CB')
Все запросы можно разделить на 4 категории:
Запросы имеют следующий вид:
for string '<строка>' do <хэш>;
Хэш может принимать одно из следующих значений (регистр имеет значение):
Общий вид запроса такой:
for string <переменная> from hash '<значение хэша>' [let …] do crack <хэш>;
Здесь хэш является одним из поддерживаемых типов хэшей (см. предыдущий раздел), значение хэша.
Подвыражение let используется для управления параметрами восстановления строки, а именно:
dict)min)max)Общий вид запроса:
for file f from '<путь к файлу>' [let …] do <хэш|validate>;
Такие запросы предназначены либо для вычисления хэша отдельных файлов, либо для валидации файлов по хэшу, что определяется видом инструкции do.
Подвыражение let используется для определения той части файла, по которой производится валидация или для которой вычисляется хэш. Если опущено, то используется весь файл целиком. Атрибуты могут быть следующие:
md5|md4|sha1|sha256|sha384|sha512|whirlpool|crc32) — имеет смысл только при валидации файла.offset)limit)Хэш может принимать одно из следующих значений (регистр имеет значение):
Общий вид запроса:
for file f from dir '<каталог>' [where ...] do <хэш|find> [withsubs];
Такие запросы предназначены либо для вычисления хэша файлов в каталоге(ах) — после do идет хэш, либо для поиска файлов (по хэшам) — после do идет ключевое слово find.
Подвыражение where используется для фильтрации файлов. Допустимые атрибуты:
name)path)size)md5|md4|sha1|sha256|sha384|sha512|whirlpool|crc32) — имеет смысл только при поиске файла.offset)limit)Опция withsubs задействует вложенные каталоги (по умолчанию выключена).
Для фильтрации файлов по имени и/или пути могут быть использованы Perl совместимые регулярные выражения (PCRE). Для фильтрации файлов по регулярным выражениям используются условные операторы ~ и !~.
Хэш может принимать одно из следующих значений (регистр имеет значение):
// Определения парсера
prog
: statement+ | EOF
;
statement
: expr NEWLINE
| NEWLINE
;
expr:
FOR (expr_string | expr_hash | expr_dir | expr_file)
;
expr_string:
STR source DO hash_clause
;
expr_hash:
STR id FROM HASH source let_clause? DO brute_force_clause
;
expr_dir
: FILE id FROM DIR source let_clause? where_clause? DO ( hash_clause WITHSUBS? | FIND WITHSUBS? )
;
expr_file
: FILE id FROM source (let_clause)? DO ( hash_clause | VALIDATE )
;
source : STRING;
id : ID;
attr_clause : ID DOT attr ;
attr : str_attr | int_attr ;
hash_clause
: MD5 | MD4 | SHA1 | SHA256 | SHA384 | SHA512 | CRC32 | WHIRLPOOL
;
brute_force_clause
: CRACK hash_clause
;
let_clause
: LET assign (COMMA assign)*
;
where_clause
: WHERE! boolean_expression
;
boolean_expression
: conditional_or_expression
;
conditional_or_expression
: conditional_and_expression (OR conditional_and_expression)*
;
conditional_and_expression
: not_expression (AND not_expression)*
;
not_expression
: exclusive_or_expression
| NOT_OP exclusive_or_expression
;
exclusive_or_expression
: relational_expr
| OPEN_BRACE boolean_expression CLOSE_BRACE
;
relational_expr
: ID DOT
( relational_expr_str
| relational_expr_int
)
;
relational_expr_str
: str_attr (EQUAL | NOTEQUAL | MATCH | NOTMATCH) STRING
;
relational_expr_int
: int_attr (EQUAL | NOTEQUAL | GE | LE | LEASSIGN | GEASSIGN) INT
;
assign
: ID DOT ( str_attr ASSIGN_OP STRING | int_attr ASSIGN_OP INT )
;
str_attr : NAME_ATTR | PATH_ATTR | DICT_ATTR | MD5 | MD4 | SHA1 | SHA256 | SHA384 | SHA512 | CRC32 | WHIRLPOOL ;
int_attr : SIZE_ATTR | LIMIT_ATTR | OFFSET_ATTR | MIN_ATTR | MAX_ATTR ;
// Определения лексера
NAME_ATTR : 'name';
PATH_ATTR : 'path' ;
DICT_ATTR : 'dict' ;
SIZE_ATTR : 'size' ;
LIMIT_ATTR : 'limit' ;
OFFSET_ATTR : 'offset' ;
MIN_ATTR : 'min' ;
MAX_ATTR : 'max' ;
CRACK : 'crack' ;
WHERE : 'where' ;
OR: 'or' ;
AND: 'and' ;
NOT_OP: 'not' ;
FOR: 'for' ;
FROM: 'from' ;
DO: 'do' ;
FIND: 'find' ;
WITHSUBS : 'withsubs' ;
VALIDATE : 'validate' ;
LET : 'let' ;
DIR : 'dir' ;
FILE : 'file' ;
HASH : 'hash' ;
STR : 'string' ;
MD5: 'md5';
SHA1: 'sha1' ;
SHA256: 'sha256' ;
SHA384: 'sha384' ;
SHA512: 'sha512' ;
MD4: 'md4' ;
CRC32: 'crc32' ;
WHIRLPOOL: 'whirlpool' ;
fragment
STRING1 : '\'' ( options {greedy=false;} : ~('\u0027' | '\u000A' | '\u000D'))* '\'' ;
fragment
STRING2 : '"' ( options {greedy=false;} : ~('\u0022' | '\u000A' | '\u000D'))* '"' ;
STRING : STRING1 | STRING2 ;
ID : ID_START ID_PART* ;
fragment
ID_START : '_' | 'A'..'Z' | 'a'..'z' ;
fragment
ID_PART : ID_START | '0'..'9' ;
INT : '0'..'9'+ ;
ASSIGN_OP : ASSIGN;
NEWLINE: ';';
WS : (' '|'\t'| EOL )+ ;
DOT : '.' ;
COMMA: ',' ;
OPEN_BRACE : '(';
CLOSE_BRACE : ')';
COMMENT : ('#' | '/' '/') ~(EOL)* CR? (LF | EOF);
fragment
EOL : LF | CR ;
fragment
LF : '\n' ;
fragment
CR : '\r' ;
PLUS: '+' ;
EQUAL: ASSIGN ASSIGN ;
NOTEQUAL: NOT ASSIGN ;
fragment
ASSIGN: '=' ;
fragment
NOT: '!' ;
GE: '>' ;
LE: '<' ;
MATCH: '~' ;
NOTMATCH : NOT MATCH ;
LEASSIGN : LE ASSIGN;
GEASSIGN : GE ASSIGN;
Вычисление SHA1 хэша для строки 123
for string '123' do sha1;
Вычисление MD5 хэша для файла
for file f from 'file.txt' do md5;
Вычисление SHA384 хэша для части файла (первый килобайт)
for file f from 'file.txt' let f.limit = 1024 do sha384;
Вычисление SHA256 хэша части файла (один килобайт с пропуском первых 512 байт)
for file f from 'file.txt' let f.limit = 1024, f.offset = 512 do sha256;
Валидация файла по его MD4 хэшу
for file f from 'file.txt' let f.md4 = 'C58CDA49F00748A3BC0FCFA511D516CB' do validate;
Вычисление SHA512 хэша всех файлов каталога c:\dir
for file f from dir 'c:\dir' do sha512;
Вычисление Whirlpool хэша всех файлов каталога c:\dir а также всех его подкаталогов
for file f from dir 'c:\dir' do whirlpool withsubs;
Вычисление CRC32 суммы всех exe файлов каталога c:\dir
for file f from dir 'c:\dir' where f.name ~ '.*exe$' do crc32;
Вычисление MD5 хэша всех файлов каталога c:\dir кроме файлов с расширением tmp
for file f from dir 'c:\dir' where f.name !~ '.*tmp$' do md5;
Вычисление MD5 хэша всех exe и dll файлов каталога c:\dir
for file f from dir 'c:\dir' where f.name ~ '.*exe$' or f.name ~ '.*dll$' do md5;
Вычисление MD5 хэша всех exe файлов каталога c:\dir исключая те из них, которые начинаются с bad
for file f from dir 'c:\dir' where f.name !~ '^bad.*' do md5;
Поиск файла на диске C:\ по известному MD4 хэшу
for file f from dir 'c:\' where f.md4 == 'C58CDA49F00748A3BC0FCFA511D516CB' do find withsubs;
Восстановление строки по её MD4 хэшу используя словарь по умолчанию
for string s from hash '3689CA24BF71B39B6612549D87DCEA68' do crack md4;
Восстановление строки по её MD4 хэшу используя свой словарь
for string s from hash '3689CA24BF71B39B6612549D87DCEA68' let s.dict = '0123456789' do crack md4;
Восстановление строки по её MD4 хэшу используя свой словарь сокращенная форма (одни цифры)
for string s from hash '3689CA24BF71B39B6612549D87DCEA68' let s.dict = '0-9' do crack md4;
Восстановление строки по её MD4 хэшу используя свой словарь сокращенная форма (одни буквы в нижнем регистре)
for string s from hash '3689CA24BF71B39B6612549D87DCEA68' let s.dict = 'a-z' do crack md4;
Восстановление строки по её MD4 хэшу используя свой словарь сокращенная форма (цифры, буквы в нижнем и верхнем регистрах)
for string s from hash '3689CA24BF71B39B6612549D87DCEA68' let s.dict = '0-9a-zA-Z' do crack md4;
Восстановление строки по её MD4 хэшу используя свой словарь и определенные длины строки
for string s from hash '3689CA24BF71B39B6612549D87DCEA68' let s.dict = '0123456789', s.min = 2, s.max = 6 do crack md4;
Использование файлов с запросами
Создайте текстовый файл queries.hq, например со следующим содержимым:
# string query - this is comment for string '123' do sha1; # file query - this is comment for file f from dir 'c:\dir' where f.name !~ '^bad.*' do md5;
Далее запустите компилятор указав ему на этот файл:
hq.exe -f queries.hqБудет выполнено 2 запроса из файла
Загружать из раздела Download.