Thanks to visit codestin.com
Credit goes to github.com

Skip to content

Commit 0094f02

Browse files
committed
Adding support for generic phpass (Wordpress, Drupal, PHPBB3, etc.) (Issue #4252)
1 parent 4591301 commit 0094f02

3 files changed

Lines changed: 25 additions & 12 deletions

File tree

lib/core/enums.py

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -177,7 +177,7 @@ class HASH(object):
177177
SHA512_GENERIC = r'(?i)\A(0x)?[0-9a-f]{128}\Z'
178178
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'
179179
JOOMLA = r'\A[0-9a-f]{32}:\w{32}\Z'
180-
WORDPRESS = r'\A\$P\$[./0-9a-zA-Z]{31}\Z'
180+
PHPASS = r'\A\$[PHQS]\$[./0-9a-zA-Z]{31}\Z'
181181
APACHE_MD5_CRYPT = r'\A\$apr1\$.{1,8}\$[./a-zA-Z0-9]+\Z'
182182
UNIX_MD5_CRYPT = r'\A\$1\$.{1,8}\$[./a-zA-Z0-9]+\Z'
183183
APACHE_SHA1 = r'\A\{SHA\}[a-zA-Z0-9+/]+={0,2}\Z'

lib/core/settings.py

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -18,7 +18,7 @@
1818
from thirdparty.six import unichr as _unichr
1919

2020
# sqlmap version (<major>.<minor>.<month>.<monthly commit>)
21-
VERSION = "1.4.7.0"
21+
VERSION = "1.4.7.1"
2222
TYPE = "dev" if VERSION.count('.') > 2 and VERSION.split('.')[-1] != '0' else "stable"
2323
TYPE_COLORS = {"dev": 33, "stable": 90, "pip": 34}
2424
VERSION_STRING = "sqlmap/%s#%s" % ('.'.join(VERSION.split('.')[:-1]) if VERSION.count('.') > 2 and VERSION.split('.')[-1] == '0' else VERSION, TYPE)

lib/utils/hash.py

Lines changed: 23 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -33,6 +33,7 @@
3333
import base64
3434
import binascii
3535
import gc
36+
import math
3637
import os
3738
import re
3839
import tempfile
@@ -481,14 +482,20 @@ def vbulletin_passwd(password, salt, **kwargs):
481482

482483
return "%s:%s" % (md5(binascii.hexlify(md5(getBytes(password)).digest()) + getBytes(salt)).hexdigest(), salt)
483484

484-
def wordpress_passwd(password, salt, count, prefix, **kwargs):
485+
def phpass_passwd(password, salt, count, prefix, **kwargs):
485486
"""
486487
Reference(s):
487488
https://web.archive.org/web/20120219120128/packetstormsecurity.org/files/74448/phpassbrute.py.txt
488489
http://scriptserver.mainframe8.com/wordpress_password_hasher.php
490+
https://www.openwall.com/phpass/
491+
https://github.com/jedie/django-phpBB3/blob/master/django_phpBB3/hashers.py
489492
490-
>>> wordpress_passwd(password='testpass', salt='aD9ZLmkp', count=2048, prefix='$P$9aD9ZLmkp')
493+
>>> phpass_passwd(password='testpass', salt='aD9ZLmkp', count=2048, prefix='$P$')
491494
'$P$9aD9ZLmkpsN4A83G8MefaaP888gVKX0'
495+
>>> phpass_passwd(password='testpass', salt='Pb1j9gSb', count=2048, prefix='$H$')
496+
'$H$9Pb1j9gSb/u3EVQ.4JDZ3LqtN44oIx/'
497+
>>> phpass_passwd(password='testpass', salt='iwtD/g.K', count=128, prefix='$S$')
498+
'$S$5iwtD/g.KZT2rwC9DASy/mGYAThkSd3lBFdkONi1Ig1IEpBpqG8W'
492499
"""
493500

494501
def _encode64(input_, count):
@@ -523,18 +530,24 @@ def _encode64(input_, count):
523530
return output
524531

525532
password = getBytes(password)
526-
salt = getBytes(salt)
533+
f = {"$P$": md5, "$H$": md5, "$Q$": sha1, "$S$": sha512}[prefix]
527534

528-
cipher = md5(salt)
535+
cipher = f(getBytes(salt))
529536
cipher.update(password)
530537
hash_ = cipher.digest()
531538

532539
for i in xrange(count):
533-
_ = md5(hash_)
540+
_ = f(hash_)
534541
_.update(password)
535542
hash_ = _.digest()
536543

537-
return "%s%s" % (prefix, _encode64(hash_, 16))
544+
retVal = "%s%s%s%s" % (prefix, ITOA64[int(math.log(count, 2))], salt, _encode64(hash_, len(hash_)))
545+
546+
if prefix == "$S$":
547+
# Reference: https://api.drupal.org/api/drupal/includes%21password.inc/constant/DRUPAL_HASH_LENGTH/7.x
548+
retVal = retVal[:55]
549+
550+
return retVal
538551

539552
__functions__ = {
540553
HASH.MYSQL: mysql_passwd,
@@ -555,7 +568,7 @@ def _encode64(input_, count):
555568
HASH.JOOMLA: joomla_passwd,
556569
HASH.DJANGO_MD5: django_md5_passwd,
557570
HASH.DJANGO_SHA1: django_sha1_passwd,
558-
HASH.WORDPRESS: wordpress_passwd,
571+
HASH.PHPASS: phpass_passwd,
559572
HASH.APACHE_MD5_CRYPT: unix_md5_passwd,
560573
HASH.UNIX_MD5_CRYPT: unix_md5_passwd,
561574
HASH.APACHE_SHA1: apache_sha1_passwd,
@@ -965,7 +978,7 @@ def dictionaryAttack(attack_dict):
965978
try:
966979
item = None
967980

968-
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):
981+
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):
969982
hash_ = hash_.lower()
970983

971984
if hash_regex in (HASH.MD5_BASE64, HASH.SHA1_BASE64, HASH.SHA256_BASE64, HASH.SHA512_BASE64):
@@ -994,9 +1007,9 @@ def dictionaryAttack(attack_dict):
9941007
item = [(user, hash_), {"salt": hash_.split(':')[-1]}]
9951008
elif hash_regex in (HASH.DJANGO_MD5, HASH.DJANGO_SHA1):
9961009
item = [(user, hash_), {"salt": hash_.split('$')[1]}]
997-
elif hash_regex in (HASH.WORDPRESS,):
1010+
elif hash_regex in (HASH.PHPASS,):
9981011
if ITOA64.index(hash_[3]) < 32:
999-
item = [(user, hash_), {"salt": hash_[4:12], "count": 1 << ITOA64.index(hash_[3]), "prefix": hash_[:12]}]
1012+
item = [(user, hash_), {"salt": hash_[4:12], "count": 1 << ITOA64.index(hash_[3]), "prefix": hash_[:3]}]
10001013
else:
10011014
warnMsg = "invalid hash '%s'" % hash_
10021015
logger.warn(warnMsg)

0 commit comments

Comments
 (0)