动态计算暴力破解大小?

0 投票
3 回答
627 浏览
提问于 2025-04-15 14:32

你如何动态计算暴力破解方法的大小呢?举个例子,如果你要把所有的IPv6地址从0:0:0:0:0:0:0:0到ffff:ffff:ffff:ffff:ffff:ffff:ffff:ffff打印到文件里,这需要多少次迭代和多少空间?这里的难点在于每一行的长度是不一样的。IP地址只是一个例子。

这个想法是,你给出格式和每部分的最大长度。所以如果变量类型是'%c'(字符),最大长度是26,那么迭代次数就是26,而在文本文件中所需的空间就是26 + 26(一个字符用作分隔符)。

def calculate(format, rules):

  end = format

  for i in rules:
    (vartype, maxlen) = rules[i]
    end = end.replace(i, vartype % maxlen)


  start = format

  for i in rules:
    (vartype, maxlen) = rules[i]
    minlen = 0
    start = start.replace(i, vartype % minlen)

  start_bytes = len(start)
  end_bytes = len(end)

  # how to add for example IPv4 calculations
  #         0.0.0.0 - 9.9.9.9
  #     10.10.10.10 - 99.99.99.99
  # 100.100.100.100 - 255.255.255.255

  iterations = 0

  for i in rules:
    if format.find(i) is not -1:
      (vartype, maxlen) = rules[i]
      if iterations == 0:
        iterations = int(maxlen) + 1
      else:
        iterations *= int(maxlen) + 1

  iterations -= 1

  needed_space = 0

  if start_bytes == end_bytes:
    # +1 for separator (space / new line)
    needed_space = (1 + start_bytes) * iterations
  else:
    needed_space = "How to calculate?"

  return [iterations, needed_space, start, end, start_bytes, end_bytes]


if __name__ == '__main__':

  # IPv4
  print calculate(
    "%a.%b.%c.%d",
    {
      '%a': ['%d', 255],
      '%b': ['%d', 255],
      '%c': ['%d', 255],
      '%d': ['%d', 255]
    },
  )

  # IPv4 zero filled version
  print calculate(
    "%a.%b.%c.%d",
    {
      '%a': ['%03d', 255],
      '%b': ['%03d', 255],
      '%c': ['%03d', 255],
      '%d': ['%03d', 255]
    },
  )


  # IPv6
  print calculate(
    "%a:%b:%c:%d:%e:%f:%g:%h",
    {
      '%a': ['%x', 65535],
      '%b': ['%x', 65535],
      '%c': ['%x', 65535],
      '%d': ['%x', 65535],
      '%e': ['%x', 65535],
      '%f': ['%x', 65535],
      '%g': ['%x', 65535],
      '%h': ['%x', 65535]
    },
  )

  # days in year, simulate with day numbers
  print calculate(
    "ddm%a", #ddmmyy
    {
      '%a': ['%03d', 365],
    },
  )

举个例子:

  • 1.2.3.4占用7个字节
  • 9.9.9.10占用8个字节
  • 1.1.1.100占用9个字节
  • 5.7.10.100占用10个字节
  • 128.1.1.1占用9个字节
  • 还有其他的

例子 0.0.0.0 - 10.10.10.10:

  iterations = 0
  needed_space = 0

  for a in range(0, 11):
    for b in range(0, 11):
      for c in range(0, 11):
        for d in range(0, 11):
          line = "%d.%d.%d.%d\n" % (a, b, c, d)
          needed_space += len(line)
          iterations += 1

  print "iterations: %d needed_space: %d bytes" % (iterations, needed_space)

迭代次数:14641 所需空间:122452字节

结果是

  print calculate(
    "%a.%b.%c.%d",
    {
      '%a': ['%d', 10],
      '%b': ['%d', 10],
      '%c': ['%d', 10],
      '%d': ['%d', 10]
    },
  )

结果:[14641, 122452]

3 个回答

0

首先,你得先算一下需要多少行。IPv6地址有128位,所以你的输出文件将会有2128行。这大约是3.4 × 1038字节,如果所有的行都是空的。而一个TB(千兆字节)大约只有1012字节,所以你需要超过3 × 1026个1TB的硬盘,仅仅是为了存放这些空的行,等到你要放数据的时候,根本不够。

如果每行存40个字节,那就需要更多的存储空间。

0

把它拆分成几个部分可能是个好主意;对于IPv4地址来说,它由四个部分组成,这四部分之间用三个点分隔。每个部分可以是1到3个字符长,字符范围是0到9、10到99和100到255。所以你可以组合出很多种可能:

comp_length = {1: 10, 2: 90, 3: 156}

你可以通过遍历每种组合来计算总长度:

def ipv4_comp_length(n=4):
    if n == 1:
        return comp_length
    res = {}
    for rest, restcnt in ipv4_comp_length(n-1).iteritems():
        for first, firstcnt in comp_length.iteritems():
             l = first + 1 + rest # "10" + "." + "0.0.127"
             res[l] = res.get(l,0) + (firstcnt * restcnt)
    return res

print sum( l*c for l,c in ipv4_comp_length().iteritems() )

需要注意的是,这里没有考虑记录分隔符(比如“1.2.3.4 1.2.3.5”中的空格)。

扩展到IPv6地址应该也比较简单,除非你想处理像0::0这样的简写IPv6地址,它等于0:0:0:0:0:0:0:0。

4

使用组合数学和离散数学:

IPv4地址的总数是256*256*256*256,这个计算结果是2的32次方,也就是4,294,967,296个地址。

而IPv6的地址数量则是2的128次方(可以想象成8组,每组有16*16*16*16)。

一个IPv4地址占用32位,所以如果把所有的IPv4地址存储在硬盘上,计算方式是32位乘以4,294,967,296个地址,结果大约是16千兆字节

而一个IPv6地址则占用128位,所以计算方式是128位乘以2的128次方地址,结果大约是5.07 * 10的30次方千兆字节

撰写回答