mirror of
https://github.com/sqlmapproject/sqlmap.git
synced 2024-11-22 09:36:35 +03:00
Adding support for generic phpass (Wordpress, Drupal, PHPBB3, etc.) (Issue #4252)
This commit is contained in:
parent
459130196a
commit
0094f02fb0
|
@ -177,7 +177,7 @@ class HASH(object):
|
||||||
SHA512_GENERIC = r'(?i)\A(0x)?[0-9a-f]{128}\Z'
|
SHA512_GENERIC = r'(?i)\A(0x)?[0-9a-f]{128}\Z'
|
||||||
CRYPT_GENERIC = r'\A(?!\d{1,3}\.\d{1,3}\.\d{1,3}\.\d{1,3}\Z)(?![0-9]+\Z)[./0-9A-Za-z]{13}\Z'
|
CRYPT_GENERIC = r'\A(?!\d{1,3}\.\d{1,3}\.\d{1,3}\.\d{1,3}\Z)(?![0-9]+\Z)[./0-9A-Za-z]{13}\Z'
|
||||||
JOOMLA = r'\A[0-9a-f]{32}:\w{32}\Z'
|
JOOMLA = r'\A[0-9a-f]{32}:\w{32}\Z'
|
||||||
WORDPRESS = r'\A\$P\$[./0-9a-zA-Z]{31}\Z'
|
PHPASS = r'\A\$[PHQS]\$[./0-9a-zA-Z]{31}\Z'
|
||||||
APACHE_MD5_CRYPT = r'\A\$apr1\$.{1,8}\$[./a-zA-Z0-9]+\Z'
|
APACHE_MD5_CRYPT = r'\A\$apr1\$.{1,8}\$[./a-zA-Z0-9]+\Z'
|
||||||
UNIX_MD5_CRYPT = r'\A\$1\$.{1,8}\$[./a-zA-Z0-9]+\Z'
|
UNIX_MD5_CRYPT = r'\A\$1\$.{1,8}\$[./a-zA-Z0-9]+\Z'
|
||||||
APACHE_SHA1 = r'\A\{SHA\}[a-zA-Z0-9+/]+={0,2}\Z'
|
APACHE_SHA1 = r'\A\{SHA\}[a-zA-Z0-9+/]+={0,2}\Z'
|
||||||
|
|
|
@ -18,7 +18,7 @@ from lib.core.enums import OS
|
||||||
from thirdparty.six import unichr as _unichr
|
from thirdparty.six import unichr as _unichr
|
||||||
|
|
||||||
# sqlmap version (<major>.<minor>.<month>.<monthly commit>)
|
# sqlmap version (<major>.<minor>.<month>.<monthly commit>)
|
||||||
VERSION = "1.4.7.0"
|
VERSION = "1.4.7.1"
|
||||||
TYPE = "dev" if VERSION.count('.') > 2 and VERSION.split('.')[-1] != '0' else "stable"
|
TYPE = "dev" if VERSION.count('.') > 2 and VERSION.split('.')[-1] != '0' else "stable"
|
||||||
TYPE_COLORS = {"dev": 33, "stable": 90, "pip": 34}
|
TYPE_COLORS = {"dev": 33, "stable": 90, "pip": 34}
|
||||||
VERSION_STRING = "sqlmap/%s#%s" % ('.'.join(VERSION.split('.')[:-1]) if VERSION.count('.') > 2 and VERSION.split('.')[-1] == '0' else VERSION, TYPE)
|
VERSION_STRING = "sqlmap/%s#%s" % ('.'.join(VERSION.split('.')[:-1]) if VERSION.count('.') > 2 and VERSION.split('.')[-1] == '0' else VERSION, TYPE)
|
||||||
|
|
|
@ -33,6 +33,7 @@ else:
|
||||||
import base64
|
import base64
|
||||||
import binascii
|
import binascii
|
||||||
import gc
|
import gc
|
||||||
|
import math
|
||||||
import os
|
import os
|
||||||
import re
|
import re
|
||||||
import tempfile
|
import tempfile
|
||||||
|
@ -481,14 +482,20 @@ def vbulletin_passwd(password, salt, **kwargs):
|
||||||
|
|
||||||
return "%s:%s" % (md5(binascii.hexlify(md5(getBytes(password)).digest()) + getBytes(salt)).hexdigest(), salt)
|
return "%s:%s" % (md5(binascii.hexlify(md5(getBytes(password)).digest()) + getBytes(salt)).hexdigest(), salt)
|
||||||
|
|
||||||
def wordpress_passwd(password, salt, count, prefix, **kwargs):
|
def phpass_passwd(password, salt, count, prefix, **kwargs):
|
||||||
"""
|
"""
|
||||||
Reference(s):
|
Reference(s):
|
||||||
https://web.archive.org/web/20120219120128/packetstormsecurity.org/files/74448/phpassbrute.py.txt
|
https://web.archive.org/web/20120219120128/packetstormsecurity.org/files/74448/phpassbrute.py.txt
|
||||||
http://scriptserver.mainframe8.com/wordpress_password_hasher.php
|
http://scriptserver.mainframe8.com/wordpress_password_hasher.php
|
||||||
|
https://www.openwall.com/phpass/
|
||||||
|
https://github.com/jedie/django-phpBB3/blob/master/django_phpBB3/hashers.py
|
||||||
|
|
||||||
>>> wordpress_passwd(password='testpass', salt='aD9ZLmkp', count=2048, prefix='$P$9aD9ZLmkp')
|
>>> phpass_passwd(password='testpass', salt='aD9ZLmkp', count=2048, prefix='$P$')
|
||||||
'$P$9aD9ZLmkpsN4A83G8MefaaP888gVKX0'
|
'$P$9aD9ZLmkpsN4A83G8MefaaP888gVKX0'
|
||||||
|
>>> phpass_passwd(password='testpass', salt='Pb1j9gSb', count=2048, prefix='$H$')
|
||||||
|
'$H$9Pb1j9gSb/u3EVQ.4JDZ3LqtN44oIx/'
|
||||||
|
>>> phpass_passwd(password='testpass', salt='iwtD/g.K', count=128, prefix='$S$')
|
||||||
|
'$S$5iwtD/g.KZT2rwC9DASy/mGYAThkSd3lBFdkONi1Ig1IEpBpqG8W'
|
||||||
"""
|
"""
|
||||||
|
|
||||||
def _encode64(input_, count):
|
def _encode64(input_, count):
|
||||||
|
@ -523,18 +530,24 @@ def wordpress_passwd(password, salt, count, prefix, **kwargs):
|
||||||
return output
|
return output
|
||||||
|
|
||||||
password = getBytes(password)
|
password = getBytes(password)
|
||||||
salt = getBytes(salt)
|
f = {"$P$": md5, "$H$": md5, "$Q$": sha1, "$S$": sha512}[prefix]
|
||||||
|
|
||||||
cipher = md5(salt)
|
cipher = f(getBytes(salt))
|
||||||
cipher.update(password)
|
cipher.update(password)
|
||||||
hash_ = cipher.digest()
|
hash_ = cipher.digest()
|
||||||
|
|
||||||
for i in xrange(count):
|
for i in xrange(count):
|
||||||
_ = md5(hash_)
|
_ = f(hash_)
|
||||||
_.update(password)
|
_.update(password)
|
||||||
hash_ = _.digest()
|
hash_ = _.digest()
|
||||||
|
|
||||||
return "%s%s" % (prefix, _encode64(hash_, 16))
|
retVal = "%s%s%s%s" % (prefix, ITOA64[int(math.log(count, 2))], salt, _encode64(hash_, len(hash_)))
|
||||||
|
|
||||||
|
if prefix == "$S$":
|
||||||
|
# Reference: https://api.drupal.org/api/drupal/includes%21password.inc/constant/DRUPAL_HASH_LENGTH/7.x
|
||||||
|
retVal = retVal[:55]
|
||||||
|
|
||||||
|
return retVal
|
||||||
|
|
||||||
__functions__ = {
|
__functions__ = {
|
||||||
HASH.MYSQL: mysql_passwd,
|
HASH.MYSQL: mysql_passwd,
|
||||||
|
@ -555,7 +568,7 @@ __functions__ = {
|
||||||
HASH.JOOMLA: joomla_passwd,
|
HASH.JOOMLA: joomla_passwd,
|
||||||
HASH.DJANGO_MD5: django_md5_passwd,
|
HASH.DJANGO_MD5: django_md5_passwd,
|
||||||
HASH.DJANGO_SHA1: django_sha1_passwd,
|
HASH.DJANGO_SHA1: django_sha1_passwd,
|
||||||
HASH.WORDPRESS: wordpress_passwd,
|
HASH.PHPASS: phpass_passwd,
|
||||||
HASH.APACHE_MD5_CRYPT: unix_md5_passwd,
|
HASH.APACHE_MD5_CRYPT: unix_md5_passwd,
|
||||||
HASH.UNIX_MD5_CRYPT: unix_md5_passwd,
|
HASH.UNIX_MD5_CRYPT: unix_md5_passwd,
|
||||||
HASH.APACHE_SHA1: apache_sha1_passwd,
|
HASH.APACHE_SHA1: apache_sha1_passwd,
|
||||||
|
@ -965,7 +978,7 @@ def dictionaryAttack(attack_dict):
|
||||||
try:
|
try:
|
||||||
item = None
|
item = None
|
||||||
|
|
||||||
if hash_regex not in (HASH.CRYPT_GENERIC, HASH.JOOMLA, HASH.WORDPRESS, HASH.UNIX_MD5_CRYPT, HASH.APACHE_MD5_CRYPT, HASH.APACHE_SHA1, HASH.VBULLETIN, HASH.VBULLETIN_OLD, HASH.SSHA, HASH.SSHA256, HASH.SSHA512, HASH.DJANGO_MD5, HASH.DJANGO_SHA1, HASH.MD5_BASE64, HASH.SHA1_BASE64, HASH.SHA256_BASE64, HASH.SHA512_BASE64):
|
if hash_regex not in (HASH.CRYPT_GENERIC, HASH.JOOMLA, HASH.PHPASS, HASH.UNIX_MD5_CRYPT, HASH.APACHE_MD5_CRYPT, HASH.APACHE_SHA1, HASH.VBULLETIN, HASH.VBULLETIN_OLD, HASH.SSHA, HASH.SSHA256, HASH.SSHA512, HASH.DJANGO_MD5, HASH.DJANGO_SHA1, HASH.MD5_BASE64, HASH.SHA1_BASE64, HASH.SHA256_BASE64, HASH.SHA512_BASE64):
|
||||||
hash_ = hash_.lower()
|
hash_ = hash_.lower()
|
||||||
|
|
||||||
if hash_regex in (HASH.MD5_BASE64, HASH.SHA1_BASE64, HASH.SHA256_BASE64, HASH.SHA512_BASE64):
|
if hash_regex in (HASH.MD5_BASE64, HASH.SHA1_BASE64, HASH.SHA256_BASE64, HASH.SHA512_BASE64):
|
||||||
|
@ -994,9 +1007,9 @@ def dictionaryAttack(attack_dict):
|
||||||
item = [(user, hash_), {"salt": hash_.split(':')[-1]}]
|
item = [(user, hash_), {"salt": hash_.split(':')[-1]}]
|
||||||
elif hash_regex in (HASH.DJANGO_MD5, HASH.DJANGO_SHA1):
|
elif hash_regex in (HASH.DJANGO_MD5, HASH.DJANGO_SHA1):
|
||||||
item = [(user, hash_), {"salt": hash_.split('$')[1]}]
|
item = [(user, hash_), {"salt": hash_.split('$')[1]}]
|
||||||
elif hash_regex in (HASH.WORDPRESS,):
|
elif hash_regex in (HASH.PHPASS,):
|
||||||
if ITOA64.index(hash_[3]) < 32:
|
if ITOA64.index(hash_[3]) < 32:
|
||||||
item = [(user, hash_), {"salt": hash_[4:12], "count": 1 << ITOA64.index(hash_[3]), "prefix": hash_[:12]}]
|
item = [(user, hash_), {"salt": hash_[4:12], "count": 1 << ITOA64.index(hash_[3]), "prefix": hash_[:3]}]
|
||||||
else:
|
else:
|
||||||
warnMsg = "invalid hash '%s'" % hash_
|
warnMsg = "invalid hash '%s'" % hash_
|
||||||
logger.warn(warnMsg)
|
logger.warn(warnMsg)
|
||||||
|
|
Loading…
Reference in New Issue
Block a user