身份证号码爆破总结

发布时间 2023-04-21 15:40:03作者: 渗透测试中心

0x01  身份证结构

位数1234567-1415、161718
代表省份城市区县年月日所在地的派出所代码奇数男偶数女随机出现的校验码

    1-6:地址码,常住户口所在地的行政区划代码

     注意:可通过该地址查询http://xzqh.mca.gov.cn/map(知道对方大概那个县市,就能查询到对方身份证开头的地址码)

    7-14:出生年月日

   15-17:顺序码,且第17为由性别决定,男性为奇数,女性为偶数

    18:校验码,将前面17位代入公式计算,结果为0-10,若为10则用x代表


举例:440106 19990101 0010

  • 44广东省,01广州市,06天河区
  • 19990101,出生年月日
  • 001,第17位为1即男性
  • 0,最后一位为校验码


注意:由于历史原因可能有些被撤销的行政区划代码,可登陆https://xingzhengquhua.bmcx.com/ 开通vip进行查询。例如:你查询的目标出生日期在90年,则可使用91年前被撤销的行政区划代码进行尝试。如果目标因为某种原因导致的更改过身份证,则可使用近年的行政区划代码进行尝试。


0x02  身份证密码字典生成

1. 生成身份证最后6位密码字典

 前提条件:知道对方的生日日期,姓名,性别

 如果需要爆破后6位,即身份证的第13~18位,那么就有10*10*10*10*10*11(最后一位有0~X共11位)种可能

  • 后6位中的第1位,即出生日期的十位,只能为0~3,即4*10*10*10*10*11
  • 而如果是针对某人而写的字典,知道目标的性别,那么第5位就可以减掉一半。男性为1/3/5/7/9,女性为0/2/4/6/8,即4*10*10*10*5*11
同时,如果知道目标的出生日期(学校发的很多信息表中都会包含出生年月日等信息),即第1~2位也可以确定了。那么需要爆破的只有15~18位,即10*10*5*11=5500,这个数量级已经对于电脑来说很轻松就可以完成。
import itertools

if __name__ == '__main__':
  date = input("出生日期: ")
  date=date[6:8:1]
  sex = '02468' if int(input("性别(男1女2): ")) % 2 == 0 else '13579' # 性别位
  check = '0123456789X' # 校验位
  other = '0123456789'   # 其它位
  nums = itertools.product(other, other, sex, check)
  cards = []
  for num in nums:
      card = date + "".join(num)
      cards.append(card)
  print(len(cards))
  print(cards)

2.生成全部18位身份证号码密码字典

前提条件:需要知道对方的前14位,包括地址码以及生日日期,以及姓名和性别
import itertools

if __name__ == '__main__':
  date = input("出生日期: ")
  date=date[6:8:1]
  sex = '02468' if int(input("性别(男1女2): ")) % 2 == 0 else '13579' # 性别位
  check = '0123456789X' # 校验位
  other = '0123456789'   # 其它位
  nums = itertools.product(other, other, sex, check)
  cards = []
  for num in nums:
      card = date + "".join(num)
      cards.append(card)
  print(len(cards))
  print(cards)

3.生成身份证后6位字典

前提条件:只需要知道对方的姓名和性别
import itertools

if __name__ == '__main__':
  sex = '02468' if int(input("性别(男1女2): ")) % 2 == 0 else '13579' # 性别位
  check = '0123456789X' # 校验位
  other = '0123456789'   # 其它位
  nums = itertools.product(other, other, sex, check)
  cards = []
  for num in nums:
      card = "".join(num)
      cards.append(card)
  print(len(cards))
  print(cards)

4.身份证号码校验脚本

factor=(7,9,10,5,8,4,2,1,6,3,7,9,10,5,8,4,2)#可能的余数存入元组
last=("1","0","x","9","8","7","6","5","4","3","2")#对应的结果存入元组

while True:
    num=input('请输入身份证号:')
    if len(num)>18 or len(num)<18:#判断身份证号格式是否正确
        print('身份证格式不正确,请重新输入')
        continue

    else:
        num1=0

        for i in range(0,17):#循环计算乘积
            num1=num1+int(num[i])*factor[i]

        num1%=11#取模

        if last[num1]==num[17]:
            print('身份证号合法')

            if int(num[16])%2==0:
                print('为女孩')
                break
            else:
                print('为男孩')
                break

        else:
            print('身份证不合法,请重新输入')
            continue

5.身份证号码最后一位校验码生成计算脚本

#coding utf-8
num = input("请输入1-17位身份证号码:")
xishu = [7, 9, 10, 5, 8, 4, 2, 1, 6, 3, 7, 9, 10, 5, 8, 4, 2]
qiumo = [1, 0, 'X', 9, 8, 7, 6, 5, 4, 3, 2]
sum = 0
for i in range(17):
    sum += int(num[i])*int(xishu[i])
yu = sum%11
yanzheng = qiumo[yu]
print("验证码为:%s"%yanzheng)
print("身份证号码为:%s%s"%(str(num),str(yanzheng)))

0x03  BP爆破身份证号码日期



{"0":"success","msg":"\u606d\u559c\u60a8\uff0c\u60a8\u5df2\u88ab\u6211\u6821\u5f55\u53d6\uff0c\u4f60\u7684\u5b66\u53f7\u4e3a02015237 \u521d\u59cb\u5bc6\u7801\u4e3a\u8eab\u4efd\u8bc1\u53f7\u7801"}

0x04 总结

在日常的渗透中,可能收集到目标系统的已打码的身份证号码,以及姓名和性别,如果收集到的身份号码生日日期已打码,可通过BP对其爆破(一般爆破的年份从1990开始),如果收集到的身份证号码对后6位进行打码可对其后面的四位进行爆破(范围为0000-9999),如果对某个特定的身份证号码进行单独爆破,可通过以上脚本生成字典对其进行爆破。