weevely3 后门分析
补了很久之前的一个坑,写的很水(大佬不用浪费时间看这篇了
原来还是在某年的 xman 题目中见到的 weevely 后门
补了很久之前的一个坑,写的很水(大佬不用浪费时间看这篇了
原来还是在某年的 xman 题目中见到的 weevely 后门
项目地址:https://github.com/gh0stkey/RGPerson
RGPerson - 随机身份生成
环境:python3
使用方法:python3 RGPerson.py
为什么需要Ta相信很多师傅们在做测试的时候经常遇到一些注册的业务功能,要填写的东西很多,我一般都是临时去百度用的信息,这样很繁琐所以决定造轮子撸了个随机身份生成的。
介绍该脚本生成信息:姓名\年龄\性别\身份证\手机号\组织机构代码\统一社会信用代码
脚本编写原理脚本的函数: genMobile()、genIdCard()、genName()、genOrgCode()、genCreditCode()
genMobile() 为随机生成手机号的函数
genName() 为随机生成姓名的函数
genIdCard() 为随机生成身份证的函数
genOrgCode() 为随机生成组织机构代码的函数
genCreditCode() 为随机生成统一社会信用代码的函数
genMobile()随机生成手机号:需要知道国内手机号的构成
1.长度为十一位
2.前三位表示运营商
现在我们只需要做到收集手机号号段的前三位以及对应的运营商:
prelist = {"133":"电信","149":"电信","153":"电信","173":"电信","177":"电信","180":"电信","181":"电信","189":"电信","199":"电信","130":"联通","131":"联通","132":"联通","145":"联通","155":"联通","156":"联通","166":"联通","171":"联通","175":"联通","176":"联通","185":"联通","186":"联通","166":"联通","134":"移动","135":"移动","136":"移动","137":"移动","138":"移动","139":"移动","147":"移动","150":"移动","151":"移动","152":"移动","157":"移动","158":"移动","159":"移动","172":"移动","178":"移动","182":"移动","183":"移动","184":"移动","187":"移动","188":"移动","198":"移动"}获取该数组的长度:len(prelist) -> 42
随机生成下标获取三位数:prelist.keys()[random.randint(0,41)]
然后再随机填补后8位即可:
def genMobile(): prelist = {"133":"电信","149":"电信","153":"电信","173":"电信","177":"电信","180":"电信","181":"电信","189":"电信","199":"电信","130":"联通","131":"联通","132":"联通","145":"联通","155":"联通","156":"联通","166":"联通","171":"联通","175":"联通","176":"联通","185":"联通","186":"联通","166":"联通","134":"移动","135":"移动","136":"移动","137":"移动","138":"移动","139":"移动","147":"移动","150":"移动","151":"移动","152":"移动","157":"移动","158":"移动","159":"移动","172":"移动","178":"移动","182":"移动","183":"移动","184":"移动","187":"移动","188":"移动","198":"移动"} three = list(prelist.keys())[random.randint(0,len(prelist)-1)] mobile = three + "".join(random.choice("0123456789") for i in range(8)) op = prelist[three] return {mobile:op} genName()随机生成姓名:中文名字通常为2、3位汉字组成
1.收集常用的姓氏随机取其一个:
def first_name(): first_name_list = ['赵', '钱', '孙', '李', '周', '吴', '郑', '王', '冯', '陈', '褚', '卫', '蒋', '沈', '韩', '杨', '朱', '秦', '尤', '许', '何', '吕', '施', '张', '孔', '曹', '严', '华', '金', '魏', '陶', '姜', '戚', '谢', '邹', '喻', '柏', '水', '窦', '章', '云', '苏', '潘', '葛', '奚', '范', '彭', '郎', '鲁', '韦', '昌', '马', '苗', '凤', '花', '方', '俞', '任', '袁', '柳', '酆', '鲍', '史', '唐', '费', '廉', '岑', '薛', '雷', '贺', '倪', '汤', '滕', '殷', '罗', '毕', '郝', '邬', '安', '常', '乐', '于', '时', '傅', '皮', '卞', '齐', '康', '伍', '余', '元', '卜', '顾', '孟', '平', '黄', '和', '穆', '萧', '尹', '姚', '邵', '堪', '汪', '祁', '毛', '禹', '狄', '米', '贝', '明', '臧', '计', '伏', '成', '戴', '谈', '宋', '茅', '庞', '熊', '纪', '舒', '屈', '项', '祝', '董', '梁'] n = random.randint(0, len(first_name_list) - 1) f_name = first_name_list[n] return f_name2.这里一开始想搜罗常用的名字,但参考了其他师傅的代码发现随机生成中文字符更好一点:
def GBK2312(): head = random.randint(0xb0, 0xf7) body = random.randint(0xa1, 0xf9) val = f'{head:x}{body:x}' st = bytes.fromhex(val).decode('gb2312') return st3.随机生成名字的第二个字:(这里用一个list做一个空值,随机取生成的汉字或空值,用于成为随机生成2位名字或3位名字)
def second_name(): second_name_list = [GBK2312(), ''] n = random.randint(0, 1) s_name = second_name_list[n] return s_name4.随机生成名字的最后一个字:(用于满足三个汉字的名字)
def last_name(): return GBK2312()5.拼接
def last_name(): return GBK2312() genIdCard()随机生成身份证:公民身份号码是由17位数字码和1位校验码组成
18位数字组合的方式是:
1 1 0 1 0 2 Y Y Y Y M M D D 8 8 8 X 区域码(6位) 出生日期码(8位) 顺序码(2位) 性别码(1位) 校验码(1位)区域码 指的是公民常住户口所在县(市、镇、区)的行政区划代码,如110102是北京市-西城区。但港澳台地区居民的身份号码只精确到省级。
出生日期码 表示公民出生的公历年(4位)、月(2位)、日(2位)。
顺序码 表示在同一区域码所标识的区域范围内,对同年、同月、同日出生的人编定的顺序号。
性别码 奇数表示男性,偶数表示女性。
最难的还是校验码的算法,参考师傅的解说:
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位数字上出现罗马数字的Ⅹ,如果余数是10,身份证的最后一位号码就是2。
测试代码如下,取了几个真实的身份证号码发现可用:
def test(id_num): id_code_list = [7, 9, 10, 5, 8, 4, 2, 1, 6, 3, 7, 9, 10, 5, 8, 4, 2] check_code_list = [1, 0, 'X', 9, 8, 7, 6, 5, 4, 3, 2] a = 0 print(len(id_num)) for i in range(17): a = a + (int(id_num[i]) * id_code_list[int(i)]) print(check_code_list[a % 11])整合一下(Copy)就变成了如下完整的代码:
def genIdCard(age,gender): area_code = ('%s' % random.choice(list(area_dict.keys()))) id_code_list = [7, 9, 10, 5, 8, 4, 2, 1, 6, 3, 7, 9, 10, 5, 8, 4, 2] check_code_list = [1, 0, 'X', 9, 8, 7, 6, 5, 4, 3, 2] if str(area_code) not in area_dict.keys(): return None datestring = str(date(date.today().year - age, 1, 1) + timedelta(days=random.randint(0, 364))).replace("-", "") rd = random.randint(0, 999) if gender == 0: gender_num = rd if rd % 2 == 0 else rd + 1 else: gender_num = rd if rd % 2 == 1 else rd - 1 result = str(area_code) + datestring + str(gender_num).zfill(3) b = result + str(check_code_list[sum([a * b for a, b in zip(id_code_list, [int(a) for a in result])]) % 11]) return b 参考https://www.cnblogs.com/evening/archive/2012/04/19/2457440.html
https://www.cnblogs.com/thunderLL/p/7682148.html
https://blog.csdn.net/ak739105231/article/details/83932151
https://github.com/jayknoxqu/id-number-util
https://blog.csdn.net/tobacco5648/article/details/50613025
https://github.com/xbeginagain/generator
上一篇 SSL VPN 研究系列文我們通報了在 Palo Alto GlobalProtect 上的 RCE 弱點,這一篇將公開我們在 Fortigate SSL VPN 上的研究,共計找到下列五個弱點:
透過不需認證的任意讀檔問題(CVE-2018-13379)加上管理介面上的 heap overflow(CVE-2018-13383),惡意使用者可直接取得 SSL VPN 的最高權限。
此外,我們也發現了一個官方後門(CVE-2018-13382),可以任意修改使用者密碼。
在回報 Fortigate 後,官方已陸續修復這些弱點,建議 Fortigate SSL VPN 的用戶更新至最新版。
細節詳細的技術細節請參閱我們的 Advisory: https://devco.re/blog/2019/08/09/attacking-ssl-vpn-part-2-breaking-the-Fortigate-ssl-vpn/
附註這系列 VPN 研究也得到了今年 BlackHat 2019 Pwnie Awards 的 pwnie for best server-side bug(年度最佳伺服器漏洞)。