哈希类型全解析:算法、MD5 相关攻击及 PHP 特性绕过

--哈希类型--

普通

算法名称 输出长度(位) 输出长度(字节) 安全性 用途
md5 128 16 不安全 数据完整性验证、密码存储等
sha1 160 20 不安全 数据完整性验证、密码存储等
sha224 224 28 数据完整性验证、数字签名等
sha256 256 32 中等 数据完整性验证、数字签名等
sha384 384 48 数字签名、加密算法等
sha512 512 64 数字签名、加密算法等
sha3_224 224 28 未来标准的 SHA-3 家族成员,适用于数字签名等
sha3_256 256 32 未来标准的 SHA-3 家族成员,适用于数字签名等
sha3_384 384 48 未来标准的 SHA-3 家族成员,适用于数字签名等
sha3_512 512 64 未来标准的 SHA-3 家族成员,适用于数字签名等
shake_128 可变 可变 SHAKE 系列是 SHA-3 家族的可变长度版本,适用于各种应用
shake_256 可变 可变 SHAKE 系列是 SHA-3 家族的可变长度版本,适用于各种应用

windows身份验证哈希

NThash 是现代Windows操作系统计算机存储用户和服务密码的哈希格式,它也通常被称为"NTLM" , 
它引用了以前的 Windows 版本用于哈希密码的格式( "LM" ),所以NThash也被称为" NT/LM " 。 

Windows 产品的 NT 命名方式,最初意味着" 新技术(New Technology)" ,从 Windows NT版本开始被使用,表示并非由MS-DOS 操作系统所构建的产品。 后面随着时间发展,最终,"NT" 成为了微软发布的标准操作系统类型,"NT" 这个名字就被删除了,但它仍然以微软的一些技术的名称存在于Windows系统中。 

你可以通过在 Windows 机器上转储(dumping ) SAM 数据库、通过使用像 Mimikatz 这样的工具或者从 ActiveDirectory的数据库NTDS.dit中 获取NTHash/NTLM哈希值。 你可能不需要继续进行权限提升来破解哈希-因为你可以进行“传递哈希”攻击, 但如果目标有一个薄弱的密码策略,直接进行哈希破解也是一个可行的选择。

--MD5--

原理

  1. 输入数据进行填充 (填充二进制信息10000...) , 使得 数据 % 512 = 448
  2. 数据中补充输入信息数据的位长信息, 占用空间64位
  3. 初始化 初始序列A、B、C、D
  4. 数据分为N * 512bit的数据分组, 将每一组又分为 16 个32bit的子分组 (分别命名为 M0~M15)
  5. 每个子分组都要进行4次运算,运算公式分别为FF、GG、HH、II, 所以总的运算次数为N*16*4

MD5扩展长度攻击

MD5强碰撞

注:最好不要在HackBar中使用,要在数据包中直接修改才行(因为太多特殊字符容易出错)

md5
$a=TEXTCOLLBYfGiJUETHQ4hAcKSMd5zYpgqf1YRDhkmxHkhPWptrkoyz28wnI9V0aHeAuaKnak

$b=TEXTCOLLBYfGiJUETHQ4hEcKSMd5zYpgqf1YRDhkmxHkhPWptrkoyz28wnI9V0aHeAuaKnak

$a=%4d%c9%68%ff%0e%e3%5c%20%95%72%d4%77%7b%72%15%87%d3%6f%a7%b2%1b%dc%56%b7%4a%3d%c0%78%3e%7b%95%18%af%bf%a2%00%a8%28%4b%f3%6e%8e%4b%55%b3%5f%42%75%93%d8%49%67%6d%a0%d1%55%5d%83%60%fb%5f%07%fe%a2

$b=%4d%c9%68%ff%0e%e3%5c%20%95%72%d4%77%7b%72%15%87%d3%6f%a7%b2%1b%dc%56%b7%4a%3d%c0%78%3e%7b%95%18%af%bf%a2%02%a8%28%4b%f3%6e%8e%4b%55%b3%5f%42%75%93%d8%49%67%6d%a0%d1%d5%5d%83%60%fb%5f%07%fe%a2

sha1
array1=%25PDF-1.3%0A%25%E2%E3%CF%D3%0A%0A%0A1%200%20obj%0A%3C%3C/Width%202%200%20R/Height%203%200%20R/Type%204%200%20R/Subtype%205%200%20R/Filter%206%200%20R/ColorSpace%207%200%20R/Length%208%200%20R/BitsPerComponent%208%3E%3E%0Astream%0A%FF%D8%FF%FE%00%24SHA-1%20is%20dead%21%21%21%21%21%85/%EC%09%239u%9C9%B1%A1%C6%3CL%97%E1%FF%FE%01%7FF%DC%93%A6%B6%7E%01%3B%02%9A%AA%1D%B2V%0BE%CAg%D6%88%C7%F8K%8CLy%1F%E0%2B%3D%F6%14%F8m%B1i%09%01%C5kE%C1S%0A%FE%DF%B7%608%E9rr/%E7%ADr%8F%0EI%04%E0F%C20W%0F%E9%D4%13%98%AB%E1.%F5%BC%94%2B%E35B%A4%80-%98%B5%D7%0F%2A3.%C3%7F%AC5%14%E7M%DC%0F%2C%C1%A8t%CD%0Cx0Z%21Vda0%97%89%60k%D0%BF%3F%98%CD%A8%04F%29%A1
array2=%25PDF-1.3%0A%25%E2%E3%CF%D3%0A%0A%0A1%200%20obj%0A%3C%3C/Width%202%200%20R/Height%203%200%20R/Type%204%200%20R/Subtype%205%200%20R/Filter%206%200%20R/ColorSpace%207%200%20R/Length%208%200%20R/BitsPerComponent%208%3E%3E%0Astream%0A%FF%D8%FF%FE%00%24SHA-1%20is%20dead%21%21%21%21%21%85/%EC%09%239u%9C9%B1%A1%C6%3CL%97%E1%FF%FE%01sF%DC%91f%B6%7E%11%8F%02%9A%B6%21%B2V%0F%F9%CAg%CC%A8%C7%F8%5B%A8Ly%03%0C%2B%3D%E2%18%F8m%B3%A9%09%01%D5%DFE%C1O%26%FE%DF%B3%DC8%E9j%C2/%E7%BDr%8F%0EE%BC%E0F%D2%3CW%0F%EB%14%13%98%BBU.%F5%A0%A8%2B%E31%FE%A4%807%B8%B5%D7%1F%0E3.%DF%93%AC5%00%EBM%DC%0D%EC%C1%A8dy%0Cx%2Cv%21V%60%DD0%97%91%D0k%D0%AF%3F%98%CD%A4%BCF%29%B1

md5截断爆破

import hashlib
from multiprocessing.dummy import Pool as ThreadPool

# MD5截断数值已知 求原始数据
# 例子 substr(md5(captcha), 0, 6)=60b7ef

def md5(s):  # 计算MD5字符串
    return hashlib.md5(str(s).encode('utf-8')).hexdigest()

keymd5 = '8ffb1'   #已知的md5截断值
md5start = 0   # 设置题目已知的截断位置
md5length = 5

def findmd5(sss):    # 输入范围 里面会进行md5测试
    key = sss.split(':')
    start = int(key[0])   # 开始位置
    end = int(key[1])    # 结束位置
    result = 0
    for i in range(start, end):
        # print(md5(i)[md5start:md5length])
        if md5(i)[0:5] == keymd5:            # 拿到加密字符串
            result = i
            print(result)    # 打印
            break

list=[]  # 参数列表
for i in range(10):   # 多线程的数字列表 开始与结尾
    list.append(str(10000000*i) + ':' + str(10000000*(i+1)))
pool = ThreadPool()    # 多线程任务
pool.map(findmd5, list) # 函数 与参数列表
pool.close()
pool.join()

sha256截断爆破

import hashlib
from multiprocessing.dummy import Pool as ThreadPool

# sha256截断数值已知 求原始数据
# 例子 substr(sha256(captcha), 0, 6)=60b7ef

def sha256(s):  # 计算sha256字符串
    return hashlib.sha256(('TQLCTF'+str(s)).encode('utf-8')).hexdigest()

keysha256 = '5625f'   #已知的sha256截断值
sha256start = 0   # 设置题目已知的截断位置
sha256length = 5

def findsha256(sss):    # 输入范围 里面会进行sha256测试
    key = sss.split(':')
    start = int(key[0])   # 开始位置
    end = int(key[1])    # 结束位置
    result = 0
    for i in range(start, end):
        # print(sha256(i)[sha256start:sha256length])
        if sha256(i)[0:5] == keysha256:            # 拿到加密字符串
            result = i
            print(result)    # 打印
            break

list=[]  # 参数列表
for i in range(10):   # 多线程的数字列表 开始与结尾
    list.append(str(10000000*i) + ':' + str(10000000*(i+1)))
pool = ThreadPool()    # 多线程任务
pool.map(findsha256, list) # 函数 与参数列表
pool.close()
pool.join()

--PHP特性--

  • 0e绕过(弱相等)**原理**: 若两边经MD5加密后的值为0exxx形式, 会被当作科学计数法, 而且结果为零,都是相等的
MD5加密后0e开头: QNKCDZO,240610708,s878926199a,s155964671a,s214587387a,s214587387a
sha1加密后0e开头: aaroZmOk aaK1STfY aaO8zKZF aa3OFF9m 0e1290633704 10932435112
双重MD5加密后0e开头: 7r4lGXCH2Ksu2JNT3BYM CbDLytmyGm2xQyaLNhWn 770hQgrBOjrcqftrlaZk
0e开头字符串加密后0e开头: 0e215962017
  • 数组绕过(强相等)(php<8) 原理: md5()与sha1()无法处理数组, 若传入的为数组, 会返回NULL, NULL===NULL
  • NAN绕过(强相等) 原理: NAN与任何数据类型(除了true)做强/弱比较均为false, 包括和NAN比较, 而md5(NAN)为一固定值 利用: 当可以构造NAN时, 即可绕过
暂无评论

发送评论 编辑评论


				
|´・ω・)ノ
ヾ(≧∇≦*)ゝ
(☆ω☆)
(╯‵□′)╯︵┴─┴
 ̄﹃ ̄
(/ω\)
∠( ᐛ 」∠)_
(๑•̀ㅁ•́ฅ)
→_→
୧(๑•̀⌄•́๑)૭
٩(ˊᗜˋ*)و
(ノ°ο°)ノ
(´இ皿இ`)
⌇●﹏●⌇
(ฅ´ω`ฅ)
(╯°A°)╯︵○○○
φ( ̄∇ ̄o)
ヾ(´・ ・`。)ノ"
( ง ᵒ̌皿ᵒ̌)ง⁼³₌₃
(ó﹏ò。)
Σ(っ °Д °;)っ
( ,,´・ω・)ノ"(´っω・`。)
╮(╯▽╰)╭
o(*////▽////*)q
>﹏<
( ๑´•ω•) "(ㆆᴗㆆ)
😂
😀
😅
😊
🙂
🙃
😌
😍
😘
😜
😝
😏
😒
🙄
😳
😡
😔
😫
😱
😭
💩
👻
🙌
🖕
👍
👫
👬
👭
🌚
🌝
🙈
💊
😶
🙏
🍦
🍉
😣
Source: github.com/k4yt3x/flowerhd
颜文字
Emoji
小恐龙
花!
上一篇
下一篇