понедельник, 20 апреля 2015 г.

Exif

Работа с Exif данными в Linux.

Просмотр данных

exif - простая консольная утилита для извлечения\экспорта Exif данных. 
exif 1.jpg
Вывод утилиты:
EXIF tags in '1.jpg_original' ('Intel' byte order):
--------------------+----------------------------------------------------------
Tag                 |Value
--------------------+----------------------------------------------------------
Ширина изображения  |3264
Длина изображения   |2448
Производитель       |Canon
Модель              |Canon PowerShot S40
Ориентация          |Right-top
X-Resolution        |72
Y-Resolution        |72
Единица разрешения  |Дюйм
Программное обеспече|XXXXXX
Дата и время        |2025:12:20 15:01:14
Позиционирование YCb|Centered
Ширина изображения  |160
Длина изображения   |120
Сжатие              |Сжатие JPEG
Ориентация          |Right-top
X-Resolution        |72
Y-Resolution        |72
Единица разрешения  |Дюйм
Время экспозиции    |1/17 сек.
Число F             |f/2,6
Exposure Program    |Приоритет диафрагмы
ISO Speed Ratings   |320
Версия EXIF         |EXIF версии 2.2
Date and Time (Origi|2025:12:20 15:01:14
Date and Time (Digit|2025:12:20 15:01:14
Настройка компоненто|Y Cb Cr -
Скорость срабатывани|4,06 EV (1/16 сек.)
Диафрагма           |2,76 EV (f/2,6)
Яркость             |0,16 EV (3,83 кд/м^2)
Смещение экспозиции |0,00 EV
Maximum Aperture Val|2,76 EV (f/2,6)
Режим замера        |Центрально-взвешенный средний
Вспышка             |Вспышка не сработала
Фокусное расстояние |13 mm
Maker Note          |98 байт неопределённых данных
Пользовательский ком|
FlashPixVersion     |FlashPix версии 1.0
Цветовое пространств|sRGB
Pixel X Dimension   |3264
Pixel Y Dimension   |2448
Режим экспозиции    |Автоэкспозиция
Баланс белого       |Автомат. баланс белого
Scene Capture Type  |Standard
Уникальный ID изобра|LJFQ29
Индекс совместимости|R98
Версия совместимости|0100
--------------------+----------------------------------------------------------
EXIF data contains a thumbnail (10660 bytes).

Удаление и изменение

Удалить все Exif данные:
exiftool -all= <имя файла>
Имя файла должно идти после пробела. Exiftool при удалении данных создаёт резервную копию файла. Во избежание этого следует использовать ключ -overwrite_original

Изменение даты
Изменить все даты ( DateTimeOriginal, CreateDate, ModifyDate):
exiftool -AllDates="2000:01:01 12:00:01" 1.jpg

***

Заголовок, автор ключевые слова (-Author, -Keywords)
exiftool -Title="Заголовок" file.jpg
Изменить данные о камере:
exiftool -model='camera obscura' 2.jpg
exiftool -moke='Canon' 2.jpg

GPS

Отредактировать GPS данные, например установить долготу в 35° 15' 30" в западном полушарии (E):


exiv2 -M "set Exif.GPSInfo.GPSLongitude 35/1 15/1 30/1" -M "set Exif.GPSInfo.GPSLongitudeRef E" 2.jpg


При необходимости можно указать расположение места съёмки прямо на карте с помощью программы GottenGeography. Используемая карта - OpenStreetMap

***
MAT - простая утилита с графическим (и консольным) интерфейсом для удаление Exif данных.

Exif online

Просмотреть Exif данные, в том числе карту и адрес можно используя онлайн сервис Jeffrey's Exif Viewer

Извлечение изображений из PDF 

Список изображений включёных в PDF
pdfimage -list <pdf-file>

page   num  type   width height color comp bpc  enc interp  object ID x-ppi y-ppi size ratio
--------------------------------------------------------------------------------------------
Syntax Warning: Invalid Font Weight
Syntax Warning: Invalid Font Weight
   1     0 image    2480  3508  rgb     3   8  jpx    yes       21  0   300   300  631K 2.5%
   1     1 image    2480  3508  rgb     3   8  image  yes       23  0   300   300 48.3K 0.2%
   1     2 mask     4960  7015  -       1   1  image  yes       23  0   600   600 48.3K 1.1%
Чтобы извлечь все изображение следует указать путь для сохранения, например текущий каталог:
pdfimage my_pdf_file.pdf .

Алсо

exiftoolgui - утилита для работы с Exif для Windows.
exiftool способна оперировать не только Exif данными, но и например метаданными в PDF файлах, помимо множества других.

Плагины для Firefox:
FxIF - показывает данные в отельном окне
Exify - отображает данные о камере и ISO поверх изображения при наведении курсора мыши.

StackOverflow: Exif manipulation library for python

Cсылки 

Программы:
Comparison of metadata editors (wiki)
exiv2
jhead  (Windows, Linux, OS-X)
ExifTool
Phatch  (multiplatform (GUI) )
GottenGeography

ExifTool – швейцарский нож фотометаданных
Алсо
Стеганография в Linux. Как спрятать информацию внутри изображения

суббота, 13 декабря 2014 г.

python notes

#!/usr/bin/env python

Справочная система

Получить справку по имени (ключевому слову, функции, пакету, ...):
pydoc3 <имя>  
Запустить веб-сервер на свободном порту и открыть заглавную страницу документации в браузере:
pydoc3 -b

*** ipython notebook

ipython - удобная оболочка для работы с интерпретатором. Имеет подсветку синтаксиса, автодополнение и множество других преимуществ перед Python shell. Работа в этой оболочке похожа на работу в математических пакетах (Mathematica, Maxima). [IPython: замена стандартного Python shell]
ipythone notebook - удобная среда для работы с ipython в браузере. Часто используется при научных и инженерных вычислениях, интегрируется с matplotlib, позволяя отображать графики в том же окне, после вызывающего блока. 

комманда запуска: ipython notebook
зайти из браузера на сервер: http://127.0.0.1:8888

включить интеграцию matplotlib:
%matplotlib inline
При необходимости установить размер и разрешение графиков
figure(figsize = (8,4), dpi=300)  # размеры в дюймах
 
# установить размер шрифтов на графиках
matplotlib.rcParams.update({'font.size': 16}) 
В ipython notebook картинка может сжиматься до очень маленького размера, если её фактические размеры слишком велики.

***

Использовать utf-8 символы в скрипте [so]:
# -*- coding: utf-8 -*-  

***

Версия интерпретатора [so]

import sys
>>> sys.version # строка содержащая информацию о версии
>>> sys.version_info # то же самое только в кортеже 
Запустить скрипт в интерактивном режиме
Выполнить скрипт, а после открыть консоль после завершения последней операции. Таким образом, можно пользоваться результатами выполнения скрипта.
python -i script.py

***

Передать код параметром интерпретатора

python -c "print('Hello World')"

Операторы можно разделять точкой с запятой.

Установить зависимости из requirements.txt

pip install -r requirements.txt
***
Установить пакет из скрипта. Скрипт должен быть запущен с правами суперпользователя.

import pip
pip.main(['install', 'python-registry'])  # установка пакета python-registry

Профилирование [wiki]

python -m cProfile -s test <script.py>

Модуль cProfile замеряет время выполнения функций и число вызовов. Данные выводятся в табличном виде.
 14417410 function calls (14416960 primitive calls) in 7.394 seconds

   Ordered by: internal time

   ncalls  tottime  percall  cumtime  percall filename:lineno(function)
  1000000    3.511    0.000    5.614    0.000 my-script.py:31(my_favorite_foo)

ncalls - число вызовов;
tottome - общее время работы (без учёта вызовов подпрограмм?);
percall - tottome / ncalls;
cumtime - общее время работы;
percall - cumtime / ncalls.

Подробнее: Profiling python with cProfile

vprof - несколько более медленный профилировщик, который однако выдаёт более наглядный результат. Программа создаёт в том числе тепловую карту кода, кодируя цветом время выполнения отдельных фрагментов кода.
После завершения работы python программы будет запущен веб-сервер и показаны разельтаты измерения работы программы. Страница с информацией автоматически откроется в браузере.


Отладка

Встроенный режим отладки есть во многих IDE, включая PyCharm. Однако, можно не прибегая к сторонним средствам воспользоваться встроенным интерактивным консольным отладчиком pdb. Для этого достаточно подключить его как модуль при запуске скрипта:
python3 -m pdb <script>
Программа запустится на выполнение, которое будет приостановлено после первой же инструкции. Список основных команд отладчика можно получить напечатав h. Остальные команды также лаконичны (small cheatsheet):
l - показать окрестности текущей строки
n - step over, next - выполнить следующую строку
s - step into - то же самое, только с входом в функции
c - continue - выполнять до точки останова

b - показать точки останова
b 123 - установить точку останова в строке 123
cl - удалить все точки останова
cl 2 - удалить точку останова с номером 2.



Именованные кортежи (named tuples) [doc]
from collections import namedtuple
Body = namedtuple('Body', 'm v')
b = Body(5, 7)
E = b.m * b.v**2 / 2
E = b[0] * b[1]**2 / 2
m, v = b 

Отдельные поля менять не позволяется, вместо этого можно создать новый кортеж: 
p = Point(x=11, y=22) 
p2 = p._replace(x=33)


***
Инвертировать список [SO]:
>>> L = [0,10,20,40]
>>> L[::-1]
[40, 20, 10, 0]
 
 

***

Python String Format Cookbook

Печать списков

Красиво напечатать список состоящий их строк:
print(', '.join(['one', 'two', 'three'])) 
В результате:
one, two, three
Строка для который вызывается метод join является разделитем. После последнего элемента списка разделитель не ставится.
Часто этот способ нужен для того, чтобы отформатировать на печеати числа с плавающей точкой:
lst = [11.334000000000001, 17.058000000000003, 22.782000000000004, 28.506000000000004, 34.230000000000004]
print(', '.join(map(lambda x: "%2.3f"%x, lst)))
Вывод:
11.334, 17.058, 22.782, 28.506, 34.230
Итератор map  применяет к каждому элементу списка lst функцию, что передаётся первым параметром. В примере лямбда-функция в свою чоредь, превращает каждое число из списка lst в строку, которая и передаются уже методу join.

Генераторы списков.

Лаконичный и элегантный способ создать список:
numbers = [1,2,3,4,5]
squares = [number*number for number in numbers] 
Сложить элементы двух списков попарно:
T = [21.036, 31.357, 41.489, 51.442, 61.227]
S = [11.334, 17.058, 22.782, 28.506, 34.230]
ST = [s + t for s, t in zip(S, T)]


*** 
Скрипт запущен под рутом? 
if os.getuid()==0:
    print "user is root" else:  
    print "user is not root"
На счёт переносимости этого кода есть разные мнения, как и на счёт самих способов проверить обладает ли правами суперпользователя скрипт stackoverflow.

***
Проверить синтаксис скрипта без его выполнения [SO]:
python -m py_compile script.py

Параметры скрипта

Получить параметры с которыми скрипт был запущен:
if len(sys.argv):
    param1 = sys.argv[1]


getopt
Скрипт обрабатывает ключи -h, ключи требующие параметра (параметрические) -f и -t (во втором параметре конструктора getopt за этими параметрами следует двоеточие ":"); а также длинные параметрические ключи --file и --text:
import getopt

# объявление и чтение параметров (ключей) скрипта
try:
  opts,args = getopt.getopt(sys.argv[1:],"hf:t:",["file","text"])
except getopt.GetoptError:
  print('invalid params')
 
# обработка ключей opt и их параметров arg
for opt,arg in opts:
  if opt=='-h':
    print(HELP)
  elif opt in ("-f", "--ifile"):
    ifile=arg
    # ...
  elif opt in ("-t", "--text"):
    text=arg
    # ... 

См. также optparse

***

Работа с ini файлами (файлами конфигурации) [SO]
import configparser 
config = configparser.ConfigParser()
config.read('FILE.INI')
print(config['DEFAULT']['path'])  # -> "/path/name/"
config['DEFAULT']['path'] = '/var/shared/'  # update
config['DEFAULT']['default_message'] = 'Hey! help me!!' # create with open('FILE.INI', 'w') as configfile: # save
config.write(configfile)


Регулярные выражения [tutorialspoint]
import re
line = "Ave Satanas!"
reg = re.compile("Ave, [a-zA-Z]*!")
if reg.match(line):
print("match")


Прочитать пароль со стандартного ввода
import getpass
pw = getpass.getpass()

***
Хранить пароли можно в системном хранилище, используя для этого библиотеку keyring:
>>> import keyring  
>>> keyring.set_password("system", "username", "password")  
>>> keyring.get_password("system", "username") 
'password'
 

Вычислить md5 хэш
import hashlib
print(hashlib.md5("whatever your string is".encode('utf-8')).hexdigest())

Процессы и потоки

Из-за использования Global Interpreter Lock в реализации языка CPython потоки фактически вополняются только по одному за раз. Поэтому параллельные вычисления занимают примерно столько же времени сколько и такие же но последовательные.
Выиграть от использование потоком можно только при работе с операциями ввода\вывода, когда можно разделить, например ожидание ввода и одновременное исполнение какого-либо кода [SO].

import threading
from time import clock
from math import sqrt

def foo(x):
    for i in range(50000000): x = sqrt(i)*n
    print("I'm finished: %f"%clock())
    return
t1 = threading.Thread(target= foo, args=(7,))
# запуск кода на выполнение
t1.start()
# ожидание завершения потока
t1.join()



***
Запустить процесс и посмотреть, что из этого получится. Например, попробовать извлечь файлы из запароленого 7z архива:
import subprocess
filename ="qwerty.7z"
password = "qwerty"
s = subprocess.Popen(["7z", "e", "-p"%password, filename], stdout=subprocess.PIPE, stderr=subprocess.STDOUT)
r = s.communicate()[0]

Процессы [doc]

Работа с процессами похожа на работу с потоками:
import multiprocessing
 
def foo(x): 
    print(x) 
 
# создание процесса p = multiprocessing.Process(target = foo, args = (1, )) 
p.start() # запуск 
p.join() # ожидание завершения 
*** Пулы процессов [link]
...
*** Queue and Pipes
...
Параллельное программирование в Python при помощи multiprocessing и shared array

 
***
Запустить приложение, которое продолжит работу после завершения скрипта:
Popen(["application"], stdout=PIPE, stderr=PIPE, close_fds=True)

***
Читать без блокировок вывод (p.stdout.readline()) процесса [stackoverflow].

***
Завершить приложение:
p = Popen(["application"], stdout=PIPE, stderr=PIPE, close_fds=True)
p.kill()
p.wait()

***
Найти процесс по имени среди запущенных в системе:
import psutil
for proc in psutil.process_iter():
if proc.name == "application":
    print("application is running") 

Сеть и Интернет

Загрузить веб страницу
from urllib import request
resp = request.urlopen("http://google.com")
resp.readline()  # содержание страницы


Библиотека для работы с XMPP (jabber) - sleekxmpp

Лёгкий (один файл) веб-фреймворк Bottle,
Легкий python веб-фреймворк: Bottle
Для тестирования можно вместо стороннего сервера использовать сервер встроеный в bottle. Функция run() запускает сервер:
from bottle import route, run 
# функция сработает при запросе страницы hello
@route('/hello') 
def hello():
    return "Hello World!" 
 
run(host='localhost', port=80, debug=True)


По-умолчанию сервер работает на порту 8080. Для пользования 80-го порта могут потребоваться права суперпользователя.

***
Собрать данные с веб-страницы 

Открыть URL в браузре по-умолчанию
import webbrowser
webbrowser.open_new('https://google.com')

Автоматизация браузера

mechanize. тестирование сайтов, заполнение и отправка форм, скачивание файлов и т.п.

selenium


Офис

reportlab
 

Математика в python

***

Pandas

Представляет богатый функционал для обработки данных.
Чтение данных из CSV файла:
pdata = pd.read_csv('file.csv', delimiter=' ')
# Получим привычные списки значений по столбцам
data = pdata.values.transpose()
 
read_csv, в отличаи от аналогичных функции numpy, по-умолчанию способена считывать сложные типы данных, такие как время. Numpy же заменит все не числа так и сохранит: Nan. Однако конвертировать, например время, из строки (как сохранит его после прочтения из csv файла pandas) в специальный формат всё же придётся.
Введение в анализ данных с помощью Pandas
Getting Started with Pandas: Kaggle's Titanic Competition

Геолокация

По публичному IP.
Будем использовать локальную БД (эту):
import GeoIP
gi = GeoIP.open('/usr/share/GeoIP/GeoIPCity.dat', GeoIP.GEOIP_STANDARD)
geo = gi.record_by_addr('8.8.8.8')
Теперь geo содержит словарь:
{'area_code': 650,
 'city': 'Mountain View',
 'country_code': 'US',
 'country_code3': 'USA',
 'country_name': 'United States',
 'dma_code': 807,
 'latitude': 37.384498596191406,
 'longitude': -122.08809661865234,
 'metro_code': 807,
 'postal_code': '94040',
 'region': 'CA',
 'region_name': 'California',
 'time_zone': 'America/Los_Angeles'}

Алсо

LearnPython.org interactive Python tutorial

Ссылки

IPython: замена стандартного Python shell
IPython: Built-in magic commands

Python: советы, уловки, хаки [eng]
Scientific Python Tips and Tricks
Программирование и научные вычисления на языке Python
Параллельное программирование в Python при помощи multiprocessing и shared array
Working with Binary Data in Python, 2015

Книги
  • Лутц М. Изучаем Python, 4-е издание, 2011, 1280 с.; (вышло 5-е издание?). В книге приводится практически полное описание языка, от простого к сложному.
  • Лутц М. Программирование на Python, том I,II, 4-е издание, 2011. Дополнение к предыдущей книге, рассматриваются популярные пакеты, посвящена практике программирования на Python.
  • Gray Hat Python: Python Programming for Hackers and Reverse Engineers; Violent Python - A Cookbook for Hackers, Forensic Analysts, Penetration Testers and Security Engineers; Книга поясвящённая вопросам информационной безопасности, практически полностью состоит из примеров.
---
Подсветка синтаксиса highlight.hohli.com

вторник, 16 сентября 2014 г.

John the Ripper

www.openwall.com/john

Получить исходники последней версии:
git clone -b bleeding-jumbo git://github.com/magnumripper/JohnTheRipper JohnTheRipper
Инструкции по компиляции - в каталоге с исходниками. Будем использовать именно эту версию сообщества. Она более функциональна, в отличие от той, что бесплатно предоставляет OpenWall.

--test - запустить бенчмарк. Для бенчмарка можно указать конкретный тип хэша, например: --format=bitcoin.




 

 

 

 

 

 

Все полученные пароли (и их хэши) сохраняются в файле $JOHN/john.pot.
Показать полученные пароли призван параметр --show file следом за которым нужно укзать файл хэшей.

Типичная строка состояние перебора (отображается по нажатию любой клавиши) выглядит так:
0g 0:00:11:27 35,46% (ETA: 23:46:35) 0g/s 133.9p/s 407.8c/s 407.8C/s SS56789..12031956
0g - число подобранных паролей
0g/s - число подобранных паролей в секунду
133.9p/s - проверок пароля в секунду (для всех хэшей)
407.8c/s - проверок хэша в секунду
407.8C/s - комбинаций пароль-хэш (?) в секунду
В этом примере подбирается пароль для трёх хэшей, поэтому число проверок хэша/сек. в три раза больше чем число проверок пароля/сек.

Linux passwords

Хэши паролей хранятся в /etc/shadow [ Understanding /etc/shadow file, wikipedia Shadow_file ].
Например, для пользователя root запись в shadow может выглядеть так:
root:X014elvznJq7E:15943:0:99999:7:::
Хэш пароля выделен зелёным.
или так
aychedee:$6$vb1tLY1qiY$M.1ZCqKtJBxBtZm1gRi8Bbkn39KU0YJW1cuMFzTRANcNKFKR4RmAQVk4rqQQCkaJT6wXqjUkFcA/qNxLyqW.U/:15405:0:99999:7:::Все поля разделены двоеточием.
1. Логин пользователя aychedee -
2. Хэш и информация о шифровании. $6$vb1tLY1qiY$M.1ZCqKtJBxBtZm1gRi8Bbkn39KU0YJW1cuMFzTRANcNKFKR4RmAQVk4rqQQCkaJT6wXqjUkFcA/qNxLyqW.U/
Здесь поля разделены знаком доллара $
2.1 Тип хэша 6
On GNU/Linux, "$1$" stands for MD5, "$2a$" is Blowfish, "$2y$" is Blowfish (correct handling of 8-bit chars), "$5$" is SHA-256 and "$6$" is SHA-512, other Unix may have different values. [man]
2.2 Соль vb1tLY1qiY
2.3 Хэш, здесь это SHA-512 (86 символов). Формат в John --format=sha512crypt
3. Число дней спустя начало эпохи UNIX (1 января 1970) до дня, когда пароль последний раз был изменён.
Остальные поля обычно используются редко и отвечают в частности за политику изменения паролей.

Пример*

cp /etc/shadow .
cp /etc/passwd .
unshadow passwd shadow > passwords
john passwords





*программу unshadow можно найти в каталоге с john

Другие типы хэшей

Явно указать тип хэша --format=<hash-type>
john --format=raw-md5 md5-text 
Указать словарь --wordlist=<wordlist-file>
john --wordlist=/pentest/john-1.7.9-jumbo5/run/password.lst hash-file.txt
Для файла с единственным md5 хэшем d8578edf8458ce06fbc5bb76a58c5ca4 вывод будет следующим:





Угаданные пароли и их число отмечены жёлтым.

Извлечение хэша

В каталоге, где располагается исполняемый файл john, присутствует множество других программ, каждая из которых выполняет ровно одно действие: извлекает хэш, например из файла-кошелка bitcoin, с которым уже может работать john.
/opt/jumbo1.8/bitcoin2john.py wallet.dat > wallet.hash
Хэш, извлечённый из зашифрованого wallet.dat
$bitcoin$96$75de603ebb2213129fcc4b8603cdaababa3e606907ebdf0da43994616ff731d60b3f9881be6a3ae4b87a36ec297f23d0$16$1d2da7bb119fd59a$158407$96$8d058a511f1411c787ccf0a08b65d2415448345b5e8f85142e7546d8bb9630b2860cd8fa69224c92fb452aaa6a8f1db1$66$03f8e808b4e4e113dd8a32d71119754be2c730a77c5a9a78719877f51ec1def0ad
Далее можно приступать к перебору:
/opt/jumbo1.8/john wallet.hash --format:Bitcoin
Loaded 1 password hash (Bitcoin [SHA512 AES 128/128 SSE4.1 2x])
Will run 4 OpenMP threads
Press 'q' or Ctrl-C to abort, almost any other key for status
12345678         (?)
1g 0:00:00:00 DONE 2/3 (2014-09-17 16:06) 1.315g/s 10.52p/s 10.52c/s 10.52C/s 123456..abc123
Use the "--show" option to display all of the cracked passwords reliably
Session completed

Алсо
 Вычислить md5 хэш можно следующим образом
echo -n "[eqyz" | openssl md5

Правила (rules) 

Синтаксис описан по ссылке выше. Правила используются для преобразования перебираемых паролей (например из словаря). Таким образом применяя правила можно увеличить (или при необходимости уменьшить) объём перебираемых паролей, преобразуется одно и то же слово в верхний\нижний регистр, повторяя его, добавляя к нему другое и т.п. Правила описываются в файле john.conf.
Самый очевидный способ это сделать, включить правила в режиме словаря
john --wordlist=all.lst --rules mypassw
Здесь нет необходимости приводить имя конкретного набора правил после ключа --rules. Правила для перебора по словарю приведены в разделе [List.Rules:Wordlist].


Добавим правило с названием CaseCASE: оставить слово как есть (:), преобразовывать в верхний регистр слово целеком (u), первую букву (с) и всё кроме первой буквы (C):
# Wordlist mode rules
[List.Rules:CaseCASE]
:
u
c
C

Теперь каждое слово из словаря будет проверятся как есть, в верхнем регистре и c заглавной буквой, нужно только указать название правила:
john hash --format=mscash --wordlist=wordlist.lst --rules=CaseCASE
Другие примеры команд используемых в описаниях правил:
t  - "переключить" раскладку в слове: Qwerty -> qWERTY;
r  - читать слова справа на лево: "Fred" -> "derF";
d  - "удвоить" слово: "Fred" -> "FredFred";
$X  - добавить символ X в конец слова;
^X  - добавить символ X в начало слова;
AN"STR" вставить строку STR в слово начиная с номера символа N
Чтобы добавить строку в конец, вместо номера символа - "z", 0 - добавить строку перед словом;
@X - удалить все вхождения символа X в слово.

Можно добавлять к слову не только постоянное выражение, но и символы из заданного диапазона:

$"[0-9]" - добавить одну цифру из диапазона от 0 до 9 в конец слова;
Az"[0-9][a-z]" - можно добавлять несколько символов из разных диапазонов;
$"[a-zA-Z]" - добавить символ из объединённых диапазонов;
$"[XYZ]" - добавить один символ из перечисленных;
Az"20[0-1][0-9]" - добавить числа с 2000 по 2019;
sXY - заменить символ X на Y.
Если производится замена одного символа на другой, то лучше сперва проверить, присутствует ли первый в слове, иначе слово останется без изменений. Получается, что john лишний раз проверит неизменённое слово. Чтобы этого избежать, сточит использовать следующее выражение
/XsXY - если в слове есть символ X, то заменить его на Y, иначе пропустить слово.


В Интернете опубликованы множество наборов правил, в том числе в wiki разработчиков john. Не обязательно добавлять новые правила в john.conf копипастой, лучше добавить файл правил указав его расположение, например: .include <KoreLogic.rules>. Здесь файл должен располагаться там же, где и john.conf.

***

Использовать John для генерации словаря (--stdout)
john --incremental --stdout > wordlist
Сессии
Продолжить предыдущую прерванную сессию:
john --restore 
при необходимости указать файл (john.rec, без расширения) в котором записана  информация (параметры и состояние) о последней сессии:
john --restore=/opt/jumbo1.8/john
Именованные сессии удобно использовать если запущенно несколько экземпляров приложения. Давать названия (--session=NAME) можно только новым сессиям. Узнать состояние предыдущей или указанной сессии --status[=NAME].

***

Отправка сообщения по окончанию процесса перебора
Процесс подбора пароля ожидаемо может быть долгим, поэтому логичным будет как-то информировать пользователя об его окончании. Самый простой путь - добавить комманду через точку с запятой после вызова john:
john --format=raw-md5 md5-text; notify-send "John complited"
Обыкновенный вывод уведомления на экран программой notify-send не подходит, то можно отправить XMPP сообщение программой sendxmpp или емейл программой mailx. [linux notes]

Если возникает необходимость настроить отправку сообщения когда john уже запущен и нет желания прерывать его работу, то можно воспользоваться простеньким однострочным скриптом:
while [ `pidof john` ]; do sleep 10; done; notify-send "..."
Скрипт будет выполнять команду sleep 10, до тех пор пока он может получить pid процесса с именем john. Затем, когда pid не будет получен (процесс john завершится) выполнится следующая комманда - notify-send. Разумеется для корректной работы скрипта нужно чтобы работал только один экземпляр процесса john.

Ссылки

http://blog.thireus.com/cracking-story-how-i-cracked-over-122-million-sha1-and-md5-hashed-passwords
http://blog.thireus.com/tag/john-the-ripper
JTR CHEAT SHEET

Crunch – Как создать словарь для брута
пароли Windows
online md5 decryptor