本文來自網友投稿。
------
0x00 前言
最近過生日,女朋友送了幾本Python黑客編程的書(沒錯,小黑闊也是可以有女朋友的)。哈哈,皮一下就是很開心。
言歸正傳,最近看這幾本Python黑客編程的書有點上頭,感覺理論是有了,就是沒有實踐。然後我就盯上了我們學校教務處(滑稽臉)。看着賬號密碼的輸入框,對着電腦相視一笑,搞一波?
我們學校的教務處系統默認密碼爲身份證號碼,於是我就打算寫一個自動生成身份證號字典的Python腳本。只要能生成一個字典,就能靠Burpsuite的Intruder功能提交Web表單,實現暴力破解。
0x01 身份證號碼結構
公民身份號碼是特徵組合碼,由十七位數字本體碼和一位校驗碼組成。排列順序從左至右依次爲:六位數字地址碼,八位數字出生日期碼,三位數字順序碼和一位數字校驗碼。
地址碼錶示編碼對象常住戶口所在縣(市、旗、區)的行政區劃代碼,按GB/T2260的規定執行。
出生日期碼錶示編碼對象出生的年、月、日,按GB/T7408的規定執行,年、月、日代碼之間不用分隔符。
順序碼錶示在同一地址碼所標識的區域範圍內,對同年、同月、同日出生的人編定的順序號,順序碼的奇數分配給男性,偶數分配給女性。
校驗碼是根據前面十七位數字碼,按照ISO 7064:1983.MOD 11-2校驗碼計算得出。
具體參考:https://baike.baidu.com/item/居民身份證號碼?fromtitle=身份證號碼&fromid=2135487
0x02 校驗碼規則
1、將前面的身份證號碼17位數分別乘以不同的係數。從第一位到第十七位的係數分別爲:7 9 10 5 8 4 2 1 6 3 7 9 10 5 8 4 2 ;
2、將這17位數字和係數相乘的結果相加;
3、用加出來和除以11,看餘數是多少;
4、餘數只可能有0 1 2 3 4 5 6 7 8 9 10這11個數字。其分別對應的最後一位身份證的號碼爲1 0 X 9 8 7 6 5 4 3 2;
5、通過上面得知如果餘數是2,就會在身份證的第18位數字上出現羅馬數字的X。
例如:某男性的身份證號碼是34052419800101001X。我們要看看這個身份證是不是合法的身份證。
首先:我們計算37+49+010+55+…+1*2,前17位的乘積和是189
然後:用189除以11得出的結果是商17餘2
最後:通過對應規則就可以知道餘數2對應的數字是x。所以,這是一個合格的身份證號碼。
具體參考:https://baike.baidu.com/item/身份證校驗碼/3800388?fr=aladdin
0x03 思路
一個完整的身份證號碼包括地址碼,出生日期碼,順序碼,校驗碼。那麼我們可以通過社工的手段獲取到對方的地址和出生日期(相信這對各位黑闊大佬,社工大佬不是什麼問題),這樣我們就得到了地址碼加出生日期碼。比如說我們知道對方是的戶籍是北京朝陽區,生於2000年1月1日,那麼我們就可以得到對方的前14位身份證號碼:11010520000101。我們再列舉出從001到999的3位順序碼,將前面的14位身份證號碼加上3位順序碼一共17位代入校驗規則中計算出校驗碼。這樣我們可以列出來的字典有999中可能。
如果我們知道對方的性別的話,我們則可以篩選一下順序碼。因爲順序碼規則中奇數分配給男性,偶數分配給女性。這樣列出來的男性身份證號的字典有500種可能,女性身份證號碼的字典則有499種可能。
0x04 代碼分析
import os #根據地址碼,出生日期碼,性別生成身份證號碼字典函數。性別可以爲空 def generator(address_code,birthday_code,sex=""): id_list=[] #如果地址碼不等於6位 if len(address_code)!=6: print "address code error" return #如果出生日期碼不等於8位 if len(birthday_code)!=8: print "birthday code error" return #如果性別爲空的話則不對順序碼進行奇偶判斷 if sex == "": for i in range(1,1000): i = repair_i(str(i)) id = address_code + birthday_code + i + cheak(address_code + birthday_code + i) id_list.append(id) #如果性別位男,則對順序碼進行奇偶判斷,如果順序碼爲偶則跳過 elif sex == "male": for i in range(1,1000): if i%2 == 0: pass else: i = repair_i(str(i)) id = address_code + birthday_code + i + cheak(address_code + birthday_code + i) id_list.append(id) #如果性別位女,則對順序碼進行奇偶判斷,如果順序碼爲奇則跳過 elif sex == "female": for i in range(1,1000): if i%2 != 0: pass else: i = repair_i(str(i)) id = address_code + birthday_code + i + cheak(address_code + birthday_code + i) id_list.append(id) return id_list #進行校驗位計算的方法 def cheak(s): sum = int(s[0]) * 7 + int(s[1]) * 9 + int(s[2]) * 10 + int(s[3]) * 5 + int(s[4]) * 8 + int(s[5]) * 4 + int(s[6]) * 2 + int(s[7]) * 1 + int(s[8]) * 6 + int(s[9]) * 3 + int(s[10]) * 7 + int(s[11]) * 9 + int(s[12]) * 10 + int(s[13]) * 5 + int(s[14]) * 8 + int(s[15]) * 4 + int(s[16]) * 2 return '10X98765432'[sum % 11] #對順序碼進行補全 def repair_i(i): #如果順序碼長度爲1,則在左邊補“00” if len(i) == 1: i = "00" + I #如果順序碼長度爲2,則在左邊補“0” elif len(i) == 2: i = "0" + i return i def main(): address = "110105" #地址碼 birthday = "20000101" #出生日期碼 sex = "male" #性別 id_list = generator(address,birthday,sex) #用系統的echo命令和“>>”輸出流,將字典列表中的每個身份證號碼輸出到txt for i in range(len(id_list)): os.system("echo " + id_list[i] + " >> " + "../IDCard_dictionary/" + address + birthday + sex + ".txt") if __name__ == "__main__": main()
0x05 寫在最後
本文源代碼鏈接:https://github.com/CrazyGeek7/IDCard_generator.git
我來自西南某不知名高校,喜歡研究網絡安全,數據挖掘,機器學習以及人工智能。這也是我第一次在微信公衆號上投稿,無論是水平還是經驗,都比不上各位大佬,文中出現的錯誤與不足請各位大佬多多指教。
我的個人郵箱是:[email protected]。
我的微博主頁是:https://weibo.com/5778036633。
我的Github主頁是:https://github.com/CrazyGeek7。