文章详情

短信预约-IT技能 免费直播动态提醒

请输入下面的图形验证码

提交验证

短信预约提醒成功

【python渗透测试】python在渗透测试中的利用(完全版,持续中出)

2023-10-12 07:19

关注

跟着gpt学习python在渗透测试中的利用


🔥系列专栏:python渗透测试
🎉欢迎关注🔎点赞👍收藏⭐️留言📝
📆首发时间:🌴2023年4月6日🌴
🍭作者水平很有限,如果发现错误,还望告知,感谢!

1. Python基础语法

注释

在Python中使用”#”单行注释或者使用三引号““”"”来进行多行注释,例如:

# 这是单行注释"""这是多行注释第一行第二行"""
变量

在Python中可以使用变量存储数据,例如:

a = 1     # 整型b = 'hello'   # 字符串c = True    # 布尔型
数据类型

Python中常用的数据类型有整型(int)、浮点型(float)、布尔型(bool)、字符串(str)等,例如:

a = 1    # 整型b = 1.1   # 浮点型c = True   # 布尔型d = 'hello'   # 字符串
运算符

在Python中支持基本的数学运算符(+,-,*,/,//,%)、比较运算符(>,<,>=,<=,==,!=)、逻辑运算符(and,or,not)等,例如:

a = 3 + 4   # 加法运算b = 5 > 2   # 大于运算c = True and False  # 逻辑与运算
控制流语句

Python中常用的控制流语句有if语句和循环语句,例如:

# if语句if a > 3:    print('a > 3')elif a == 3:    print('a == 3')else:    print('a < 3')# 循环语句for i in range(10):    print(i)while True:    print('hello')

接下来,我们将依次讲解Python在渗透测试中的应用。

二、 模块

1. requests

  1. 第一个模块是requests。requests模块提供了很多基本的HTTP请求方法,比如get(), post(), put(), delete()、head()等。这些方法都包含URL作为第一个参数,并且一些可选的参数,用于配置HTTP请求中的不同组件,例如HTTP头或请求体,内容类型、文件对象等等。

在渗透测试过程中,requests最重要的请求方法是get()和post():

GET请求
requests.get(url, params=None, **kwargs)

其中,参数url是请求的URL,params是请求的查询参数字典,**kwargs包含其他可选参数。

示例:

import requestsresponse = requests.get('http://httpbin.org/get', params={"name":"john", "age":"32"})print(response.text)

上述代码向httpbin服务发送了一条GET请求,查询参数为"name":“john”, “age”:“32”,并将响应内容打印出来。

POST请求
requests.post(url, data=None, json=None, **kwargs)

其中,参数url是请求的URL,data是请求体中包含的数据字典,json是可选的Json格式数据。**kwargs向请求中添加其他可选参数。

示例:

import requestsdata = {'name': 'john', 'age': '32'}response = requests.post('http://httpbin.org/post', data=data)print(response.text)

上述代码向httpbin服务发送一条POST请求,如同一个在线表单提交,将请求数据发送到服务端,并将响应内容打印出来。

除了get()和post()方法,requests模块还提供如下常用的渗透测试方法:

控制请求头

可以使用headers参数来控制HTTP请求头内容,常常用于伪造User-Agent等信息。

import requestsheaders = {'User-Agent': 'Mozilla/5.0'}response = requests.get('http://httpbin.org/get', headers=headers)print(response.text)
控制超时时间

使用timeout参数来控制请求的超时时间,避免因长时间等待服务的响应而导致的等待阻塞。

import requestsresponse = requests.get("https://www.baidu.com", timeout=10)

这段代码使用requests库发送了一个GET请求到百度,并设置了超时时间为10秒钟。意思是如果10秒内没有收到响应,就自动停止请求,防止出现无限等待的情况。
需要注意的是,timeout参数可以在两种情况下使用:

  1. 连接超时:如果在该时间内没有建立连接,那么就停止请求并且抛出一个异常。
  2. 读取超时:如果建立连接之后,服务器在timeout时间内没有返回任何数据,就会引发一个异常。
控制响应编码

使用response.encoding属性来控制响应的编码方式(默认是ISO-8859-1),也可以让requests自动检测响应内容的编码方式。

import requestsresponse = requests.get(url)print(response.encoding)response.encoding = "utf-8"print(response.encoding)

自动选择适应的编码方案

import requestsr = requests.get('https://www.baidu.com')print(r.text)   # 自动检测响应内容的编码方式,并使用正确的编码方式来解析响应内容
处理Cookies

使用requests库发送请求后,可以从响应中获取服务器发送的Cookie并保存到Session中。Session会自动向所有后续的请求中添加对应的Cookie。

import requestss = requests.Session()response = s.get(url)print(response.cookies)

这段代码是创建一个Session对象s,使用s对象发送一个GET请求,获取响应内容中包含的Cookie信息,并打印输出。

处理SSL验证

可以使用verify参数来控制是否验证SSL证书的有效性。

import requestsresponse = requests.get(url, verify=False)

verify参数也可以指定证书路径,来绕过自签名证书的验证。

处理代理服务器

可以向requests发送请求时使用代理服务器。

import requestsproxies = {  "http": "http://127.0.0.1:8080",   "https": "http://127.0.0.1:8080",}response = requests.get("http://httpbin.org", proxies=proxies)

上述代码向httpbin发送请求的时候使用了127.0.0.1:8080这个代理服务器。

文件上传

使用requests库向服务端发送带有文件的请求,可以通过 files 参数来实现。files 参数是一个字典类型,包含需要上传的文件的信息。文件名和文件路径解释如下:

键值对描述
key用于服务端获取文件的 key
path文件的路径
filename文件的名称
mime文件的类型
    r:以只读模式打开文件(默认模式),允许读取文件内容但不允许写入或修改文件。    w:以写入模式打开文件,允许向文件中写入新数据,如果文件已存在,则会覆盖原有内容。    a:以追加模式打开文件,允许向文件末尾追加新数据,如果文件不存在,则创建一个新文件。    x:以独占方式打开文件,如果文件不存在,则创建一个新文件,否则会报错。    b:以二进制模式打开文件,通常与上述模式一起使用,例如rb、wb等。    t:以文本模式打开文件,也是默认模式,通常与上述模式一起使用,例如rt、wt等。

示例:

import requestsurl = 'http://httpbin.org/post'files = {'file': ('test.txt', open('test.txt', 'rb'), 'text/plain')}response = requests.post(url, files=files)print(response.text)
文件下载

使用requests库从服务端下载文件,可以直接使用get()方法,并指定参数stream=True来分块下载文件。文件以二进制形式存储。

import requestsurl = 'http://example.com/file.png'response = requests.get(url, stream=True)with open('file.png', 'wb') as f:    for chunk in response.iter_content(chunk_size=128):        f.write(chunk)

解释如下:

    import requests:导入requests库,用于发送HTTP请求    url = 'http://example.com/file.png':定义要下载的文件的URL地址    response = requests.get(url, stream=True):向该URL地址发送GET请求,并将响应对象赋值给变量response。设置stream=True参数以启用流式传输模式,这样可以在接收响应时逐块处理数据,避免一次性将大量数据读入内存而导致程序崩溃。    with open('file.png', 'wb') as f::打开名为file.png的二进制文件,以写入模式(即覆盖已有内容)。由于图片是二进制文件,所以需要以'wb'方式打开,表示以二进制写入模式打开文件。    for chunk in response.iter_content(chunk_size=128)::迭代处理响应对象的内容,每次读取128字节的数据块。iter_content()方法会返回一个生成器,逐块返回响应正文的数据。因为我们设置了stream=True参数,所以在读取数据时不会将整个响应载入内存,而是一块一块地读取,从而节省内存。    f.write(chunk):将当前数据块写入文件中。通过循环,将整个响应正文一块一块地写入本地文件。

2. OS

1. 在目标主机上寻找敏感文件:

os.path.exists(filename):检查指定路径的文件是否存在,返回布尔值。

import osfilename = '/etc/passwd'if os.path.exists(filename):    print(f'{filename} exists')else:    print(f'{filename} does not exist')
2. 修改配置文件:
with open(filename, 'r') as f::使用with语句打开文件,并在执行完代码块后自动关闭文件。'r'表示以只读模式打开文件。f.readlines():从文件中读取所有行,并将其作为列表返回。with open(filename, 'w') as f::使用with语句以写入模式打开文件。f.writelines(lines):将字符串列表lines写入文件中。
import osfilename = 'config.ini'with open(filename, 'r') as f:    lines = f.readlines()for i, line in enumerate(lines):    if line.startswith('password='):        lines[i] = 'password=new_password\n'with open(filename, 'w') as f:    f.writelines(lines)
3. 破解密码文件:
import osfilename = '/etc/shadow'with os.open(filename, os.O_RDONLY) as f:    data = os.read(f, 1024)    # perform brute-force or dictionary attack on the data
这段代码是用来在Python中操作文件并进行密码破解的实例。具体解释如下:    filename = '/etc/shadow' 表示定义要读取的文件名为'/etc/shadow'with os.open(filename, os.O_RDONLY) as f: 表示用只读模式打开文件,并赋值给f。这里使用了Python的with语句,这样在函数执行完毕后会自动关闭文件。    data = os.read(f, 1024) 表示读取文件中的1024个字节数,并赋值给变量data。在渗透测试中,我们通常需要在文件中进行密码破解,这里的代码可以读取文件并将需要破解的数据存储在变量data中。    # perform brute-force or dictionary attack on the data 是一个注释,表示我们可以对data中的数据进行暴力破解或字典攻击。需要注意的是,对于一些敏感文件,如'/etc/shadow',需要有足够的权限才能读取,否则会出现权限错误。另外,在使用此代码进行密码破解时,需要遵守使用道德和法律,禁止进行未授权的攻击和侵入他人隐私的行为。
4. 启动或停止服务:
import osservice_name = 'mysql'os.system(f'net start {service_name}')
5. 执行系统命令:
import osos.system('echo hello world')
6. 操作进程:
import osimport signalpid = 1234os.kill(pid, signal.SIGTERM)这段代码将会向 ID 为 1234 的进程发送 SIGTERM 信号,要求它正常退出。如果该进程无法响应,您可以尝试使用其他信号,例如 SIGKILL 强制终止它。
7. 获取网络配置信息:
import osip_address = os.popen('ifconfig | grep "inet " | awk \'{print $2}\'').read().strip()mac_address = os.popen('ifconfig | grep "ether " | awk \'{print $2}\'').read().strip()
    os.popen(command):这个方法会在一个子进程中执行参数 command 指定的命令,并返回一个类似于文件对象的可读对象,它可以被用来读取该命令的输出。在这段代码中,我们使用了 os.popen() 方法来执行 shell 命令获取 IP 地址和 MAC 地址。    ifconfig | grep "inet " | awk '{print $2}':这个命令会通过 ifconfig 命令获取本机的网络配置信息,并使用管道符 | 连接起来的三个工具进行处理,最后得到本机的 IP 地址。其中:    grep "inet ":筛选出含有 "inet " 的行(即包含 IP 地址的行)。    awk '{print $2}':提取出每行的第二个字段,即 IP 地址。awk 是一种非常强大的文本处理工具,它能够按照指定的分隔符对每行文本进行切割,并提取出指定字段的值。    ifconfig | grep "ether " | awk '{print $2}':这个命令同样使用管道符连接了三个工具,用于获取本机的 MAC 地址。其中:    grep "ether ":筛选出含有 "ether " 的行(即包含 MAC 地址的行)。    awk '{print $2}':提取出每行的第二个字段,即 MAC 地址。    strip():这个方法用于去除字符串两端的空白字符(包括换行符、制表符等),使得最终获得的 IP 地址和 MAC 地址不含有多余的空格或换行符。

3. socket

下面是一些使用Python socket模块进行渗透测试的示例代码:

1. 网络扫描

下面的脚本演示了如何使用socket模块进行端口扫描:

import sockettarget = "127.0.0.1"ports = [21, 22, 80, 443, 3389]for port in ports:    s = socket.socket(socket.AF_INET, socket.SOCK_STREAM)    s.settimeout(1)    result = s.connect_ex((target, port))    if result == 0:        print(f"Port {port} is open.")    s.close()

在上述代码中,我们首先定义了目标IP地址和要扫描的端口列表。然后,我们循环遍历这些端口,并使用socket.socket()函数创建套接字对象。我们使用AF_INET地址族和SOCK_STREAM套接字类型指定TCP/IP协议。

接着,我们使用connect_ex()方法连接到目标主机和端口。如果返回值为0,则表示端口开放,可以进行进一步的渗透测试或攻击。

最后,我们关闭套接字以释放资源。

2. 远程连接

下面的示例演示了如何使用socket模块建立远程连接:

import sockettarget_host = "www.google.com"target_port = 80client = socket.socket(socket.AF_INET, socket.SOCK_STREAM)client.connect((target_host, target_port))client.send(b"GET / HTTP/1.1\r\nHost: google.com\r\n\r\n")response = client.recv(4096)print(response)

这是一个使用Python编写的脚本,利用socket模块创建TCP连接到IP地址为"www.google.com",端口号为80的Web服务器。然后它使用HTTP/1.1协议发送了一个HTTP GET请求,请求该网站的根页面(“/”),并包括一个指定"google.com"的主机头(Host header)。

发送请求后,脚本等待从服务器接收最多4096个字节的响应数据,然后将其打印到控制台。

这个脚本基本上检索了Google主页的HTML内容,并在控制台上显示出来。但是请注意,有些网站可能会将请求重定向到不同的URL或需要在请求中包括其他标头或身份验证令牌才能成功检索。
语法点:

  1. b的作用
    在这个例子中,"GET / HTTP/1.1\r\nHost: google.com\r\n\r\n"是一个ASCII编码的文本字符串,而socket.send()方法需要接收一个字节串作为参数,所以使用了b前缀将字符串转换为字节串,以便能够正确发送给服务器。

  2. /r/n的作用
    /r/n的作用是换行,在windows中通常需要/r/n,在linux中是/r
    但是为了兼容,通常均使用/r/n来确保
    而这段代码中最后出现的两次换行是因为
    在HTTP协议中,每个报文都由三部分组成:请求行、消息报头和实体主体。
    在发送HTTP请求时,第一行是请求行,后面跟着一些请求头(Request Headers),最后以空行作为请求头的结束标志。这个空行就是一个"\r\n",也就是两个回车换行符。
    因此,当我们需要向服务器发送HTTP请求时,需要在请求头和请求行之间插入一个空行,以告诉服务器请求头已经结束,开始发送请求数据。所以,“GET / HTTP/1.1\r\nHost: google.com\r\n\r\n"中的两个”\r\n"就是表示请求头结束的空行。

3. 网络嗅探

下面的示例演示了如何使用Python socket模块进行网络嗅探:

import socketimport struct# IP头部解析函数def parse_ip_header(data):    header = struct.unpack("!BBHHHBBH4s4s", data[:20])    return {'version': (header[0] >> 4), 'header_length': (header[0] & 0xF),            'ttl': header[5], 'protocol': header[6], 'source_address': socket.inet_ntoa(header[8]),            'destination_address': socket.inet_ntoa(header[9])} # 创建原始套接字对象s = socket.socket(socket.AF_INET, socket.SOCK_RAW, socket.IPPROTO_IP)s.bind(("127.0.0.1", 0))s.setsockopt(socket.IPPROTO_IP, socket.IP_HDRINCL, 1)s.ioctl(socket.SIO_RCVALL, socket.RCVALL_ON)# 接收数据包并解析IP头部while True:    data, address = s.recvfrom(65535)    ip_header = parse_ip_header(data[:20])    print(f"Source IP: {ip_header['source_address']} Destination IP: {ip_header['destination_address']}")

代码解析;

import socketimport struct导入了socket和struct库,这两个库都是Python内置的标准库。socket库用于网络通信,而struct库则提供了一种将二进制数据按照指定格式进行解析的方式。def parse_ip_header(data):    header = struct.unpack("!BBHHHBBH4s4s", data[:20])    return {'version': (header[0] >> 4), 'header_length': (header[0] & 0xF),            'ttl': header[5], 'protocol': header[6], 'source_address': socket.inet_ntoa(header[8]),            'destination_address': socket.inet_ntoa(header[9])}定义了一个名为parse_ip_header的函数,该函数用于解析IP头部信息。它接受一个data参数,表示要解析的原始字节流。在函数内部,使用struct.unpack()方法按照IP头部的格式将data字节流进行解析,并将结果存储在一个元组中。然后,将元组中的各个字段赋值给一个字典,并返回该字典作为解析结果。其中,源地址和目的地址需要通过socket.inet_ntoa()方法将其转换为人类可读的形式。s = socket.socket(socket.AF_INET, socket.SOCK_RAW, socket.IPPROTO_IP)创建了一个socket对象,并指定它的地址族为IPv4(AF_INET),套接字类型为原始套接字(SOCK_RAW),协议为IP(IPPROTO_IP)。s.bind(("127.0.0.1", 0))将socket对象与本机的地址进行绑定,这里使用了一个元组表示IP地址和端口号。本机的IP地址为127.0.0.1,也就是通常所说的“localhost”。s.setsockopt(socket.IPPROTO_IP, socket.IP_HDRINCL, 1)设置IP_HDRINCL套接字选项,以便告诉内核不要向传出数据包添加IP头部。这样可以让我们手工构造IP头部数据和TCP/UDP等应用层协议,用于实现自己的网络协议栈或者网络嗅探。s.ioctl(socket.SIO_RCVALL, socket.RCVALL_ON)使用socket.ioctl()方法启用混杂模式(RCVALL_ON),以便套接字可以接收所有传入的数据包,无论其目的地如何。混杂模式可以让套接字从网络中收到所有传入的数据包,而不仅仅是它们所目标的那些。while True:    data, address = s.recvfrom(65535)    ip_header = parse_ip_header(data[:20])    print(f"Source IP: {ip_header['source_address']} Destination IP: {ip_header['destination_address']}")在一个无限循环中,使用recvfrom()方法从socket中接收数据包,并将数据包存储在data变量中。然后,调用parse_ip_header()函数解析IP头部信息,并将源地址和目的地址打印出来,以便进行进一步分析。

首先,需要了解一下IP头部的结构。IP头部总长度为20字节,其中前20位是固定的,后面还有一些可选的字段。在这段代码中,使用了struct库的unpack函数将收到的二进制数据按照IP头部的格式进行解析,得到一个元组。然后,通过将元组中的各个字段赋值给一个字典,将IP头部的各个字段名对应到相应的值。

接下来,创建了一个原始套接字,并将其与本机的IP地址进行绑定。这里使用了AF_INET(IPv4地址族)、SOCK_RAW(原始套接字类型)和IPPROTO_IP(IP协议)。同时,设置了IP_HDRINCL套接字选项,以通知内核不要向传出数据包添加IP头。最后,使用socket.ioctl()方法启用混杂模式,以便套接字可以接收所有传入的数据包,无论其目的地如何。混杂模式可以让套接字从网络中收到所有传入的数据包,而不仅仅是它们所目标的那些。

在上述代码中,我们使用socket模块创建了一个原始套接字对象。我们使用socket.AF_INET指定IP地址族,socket.SOCK_RAW指定原始套接字类型,socket.IPPROTO_IP表示要使用IP协议。

接着,我们绑定套接字到本地IP地址,并设置IP_HDRINCL选项以启用自定义IP头部。最后,我们使用SIO_RCVALL和RCVALL_ON选项开启嗅探。

在while循环中,我们使用recvfrom()方法接收数据包,并使用parse_ip_header()函数解析IP头部。然后,我们打印源IP和目标IP地址以分析流量并检测攻击。

4. DoS攻击
import sockettarget = "127.0.0.1"port = 80client = socket.socket(socket.AF_INET, socket.SOCK_STREAM)client.connect((target, port))for i in range(100):    client.send(b"GET / HTTP/1.1\r\nHost: google.com\r\n\r\n")client.close()

在上述代码中,我们创建一个TCP客户端套接字,并使用connect()方法连接到目标主机的指定端口。然后,我们循环发送大量无效HTTP GET请求。

由于每个请求都会占用一些服务器资源,因此这种DoS攻击可能会导致服务器崩溃或变得不可用。

这个没啥可说的,就跟连接一样

5. 编写自定义协议

下面的示例演示了如何使用Python socket模块编写自定义协议的实现:

服务端代码:

import socketdef handle_client(client_socket):    request = client_socket.recv(1024)    print(f"Received message: {request.decode('utf-8')}")    client_socket.send(b"ACK!")    client_socket.close()server = socket.socket(socket.AF_INET, socket.SOCK_STREAM)server.bind(("127.0.0.1", 8080))server.listen(1)while True:    client, address = server.accept()    print(f"Accepted connection from {address[0]}:{address[1]}")    handle_client(client)

客户端代码:

import socketclient = socket.socket(socket.AF_INET, socket.SOCK_STREAM)client.connect(("127.0.0.1", 8080))client.send(b"Hello, server!")response = client.recv(1024)print(f"Received message: {response.decode('utf-8')}")client.close()

在上述代码中,我们首先定义了一个handle_client()函数来处理客户端请求。该函数接收客户端套接字对象作为参数,并使用recv()方法接收客户端发送的数据。然后,它打印接收到的消息并使用send()方法发送响应。最后,它关闭客户端套接字以释放资源。

服务器端首先创建一个套接字对象,并将其绑定到本地IP地址和端口。然后,它开始监听连接请求,并在while循环中等待客户端连接。一旦客户端连接成功,服务器就会调用handle_client()函数以处理客户端请求。最后,服务器关闭套接字以释放资源。

客户端首先创建一个套接字对象,并使用connect()方法连接到服务器的指定端口。然后,它使用send()方法发送一个简单的“Hello, server!”消息,并使用recv()方法接收服务器的响应。最后,客户端关闭套接字以释放资源。

4. selenium

  1. 第四个模块是selenium。它是一个Python库,主要用于Web前端自动化测试和Web爬虫。以下是一个简单的使用selenium模块的Python脚本:
from selenium import webdriverurl = "https://www.example.com/login"browser = webdriver.Firefox()browser.get(url)username = browser.find_element_by_name("username")username.send_keys("admin")password = browser.find_element_by_name("password")password.send_keys("123456")login_button = browser.find_element_by_name("login")login_button.click()

在这个简单的Python脚本中,我们使用selenium.webdriver.Firefox()方法创建一个Firefox浏览器实例,使用selenium.webdriver.get()方法打开一个网站,使用selenium.webdriver.find_element_by_name()方法查找表单元素,使用selenium.webdriver.send_keys()方法输入用户名和密码,最后使用selenium.webdriver.click()方法点击登录按钮。你可以根据实际情况修改这个脚本,例如更改浏览器、查找元素的方法等等。

1. 检查Web应用程序是否存在XSS漏洞
from selenium import webdriverfrom selenium.webdriver.common.alert import Alert# 创建 Firefox WebDriver 实例driver = webdriver.Firefox()# 打开 example.com 网站并注入一个触发 XSS 攻击的脚本driver.get("http://example.com/search?q=")# 创建 Alert 对象,用于检查是否弹出了警告框alert = Alert(driver)# 断言警告框中是否包含 "XSS" 文字assert "XSS" in alert.text# 关闭警告框,并关闭浏览器窗口alert.accept()driver.close()

这段代码使用 Selenium WebDriver 来测试网站是否存在 XSS 漏洞。
首先,我们导入需要的库:selenium 和 selenium.webdriver.common.alert。然后,创建一个 Firefox WebDriver 实例,用于控制 Firefox 浏览器。

接着,我们使用 WebDriver 打开 example.com 网站,并在搜索框中注入一个触发 XSS 攻击的脚本。这个脚本会向页面注入一个 JavaScript 代码,用于触发一个弹出框。

接下来,我们创建了一个 Alert 对象实例,该对象用于检查是否弹出了警告框。如果页面中成功触发了 XSS 攻击,就会弹出一个警告框,其中包含 “XSS” 这个文字。我们使用 Python 的断言语句 assert 来判断警告框中是否包含了 “XSS”。

最后,我们通过 alert.accept() 方法关闭了弹出的警告框,并使用 driver.close() 方法关闭了浏览器窗口。

2. 模拟登录
from selenium import webdriverdriver = webdriver.Firefox()driver.get("http://example.com/login")# 输入用户名和密码username = driver.find_element_by_name("username")username.send_keys("myusername")password = driver.find_element_by_name("password")password.send_keys("mypassword")# 点击登录按钮login_button = driver.find_element_by_xpath("//button[@type='submit']")login_button.click()# 验证是否成功登录assert "Welcome" in driver.page_source# 关闭浏览器窗口driver.close()
3. 自动化扫描
from selenium import webdriverdriver = webdriver.Firefox()driver.get("http://example.com")# 执行自动化扫描# ...# 关闭浏览器窗口driver.close()
4. 模拟用户行为
from selenium import webdriverdriver = webdriver.Firefox()driver.get("http://example.com")# 模拟点击链接link = driver.find_element_by_link_text("Click Here")link.click()# 填写表单username = driver.find_element_by_name("username")username.send_keys("myusername")password = driver.find_element_by_name("password")password.send_keys("mypassword")# 发送电子邮件email_button = driver.find_element_by_xpath("//button[@id='send-email']")email_button.click()# 关闭浏览器窗口driver.close()
5. 自动化Web应用程序功能测试
from selenium import webdriverdriver = webdriver.Firefox()driver.get("http://example.com")# 输入搜索关键字并执行搜索search_box = driver.find_element_by_name("q")search_box.send_keys("keyword")search_box.submit()# 验证搜索结果是否正确assert "Search Results" in driver.title# 关闭浏览器窗口driver.close()
7. 识别验证码
from selenium import webdriverfrom PIL import Imageimport pytesseractdriver = webdriver.Firefox()driver.get("http://example.com/login")# 获取验证码图片captcha_image = driver.find_element_by_xpath("//img[@class='captcha']")captcha_image_url = captcha_image.get_attribute("src")captcha_image_data = requests.get(captcha_image_url).contentwith open("captcha.png", "wb") as f:    f.write(captcha_image_data)# 识别验证码captcha_text = pytesseract.image_to_string(Image.open("captcha.png"))# 输入用户名、密码和验证码并登录username = driver.find_element_by_name("username")username.send_keys("myusername")password = driver.find_element_by_name("password")password.send_keys("mypassword")captcha = driver.find_element_by_name("captcha")captcha.send_keys(captcha_text)login_button = driver.find_element_by_xpath("//button[@type='submit']")login_button.click()# 验证是否成功登录assert "Welcome" in driver.page_source# 关闭浏览器窗口driver.close()
8. 测试反爬虫机制
from selenium import webdriverfrom selenium.webdriver.common.keys import Keysdriver = webdriver.Firefox()driver.get("http://example.com")# 模拟用户行为以避免被检测为爬虫search_box = driver.find_element_by_name("q")
9. 自动化发现网站的登录页面

在渗透测试中,通常需要尝试暴力破解网站的登录凭证。但是在进行暴力破解之前,我们需要先确定网站的登录页面位置。使用Selenium可以自动化地发现网站的登录页面,从而加快渗透测试过程。

from selenium import webdriver# 初始化Chrome浏览器browser = webdriver.Chrome()# 打开目标URLurl = 'http://example.com'browser.get(url)# 查找登录链接并点击login_link = browser.find_element_by_xpath('//a[@href="/login"]')login_link.click()# 关闭浏览器browser.quit()
10.爬取隐藏在前端代码中的数据

有些网站会在前端代码中隐藏敏感数据,例如API密钥或者其他机密信息。使用Selenium可以自动化地打开网页并解析前端代码,从而获取这些隐藏数据。

from selenium import webdriver# 初始化Chrome浏览器browser = webdriver.Chrome()# 打开目标URLurl = 'http://example.com/hidden-data'browser.get(url)# 获取前端代码html = browser.page_source# 解析代码以获取敏感数据api_key = parse_html_for_api_key(html)# 关闭浏览器browser.quit()

这个示例代码演示了如何使用Selenium获取隐藏在前端代码中的敏感数据。注意,需要自己定义parse_html_for_api_key函数来解析HTML并找到目标数据。

5. paramiko

  1. 第五个模块是paramiko。它是一个Python库,主要用于SSH和SCP等协议的远程连接和文件传输。以下是一个简单的使用paramiko模块的Python脚本:
import paramikohost = "www.example.com"port = 22username = "admin"password = "123456"ssh = paramiko.SSHClient()ssh.set_missing_host_key_policy(paramiko.AutoAddPolicy())ssh.connect(host, port, username, password)stdin, stdout, stderr = ssh.exec_command("ls -al")result = stdout.read().decode()print(result)sftp = ssh.open_sftp()sftp.put("local_file.txt", "remote_file.txt")sftp.get("remote_file.txt", "local_file.txt")sftp.close()ssh.close()

在这个简单的Python脚本中,我们使用paramiko.SSHClient()方法创建一个SSH连接对象,使用ssh.connect()方法连接远程服务器,使用ssh.exec_command()方法执行一个命令,使用sftp.put()和sftp.get()方法传输文件,最后使用ssh.close()方法关闭SSH连接。你可以根据实际情况修改这个脚本,例如更改用户名和密码、添加密钥、更改命令等等。

三、python的实际应用

1. 信息收集

信息收集是渗透测试的第一步,Python可以用来编写各种信息收集脚本,例如端口扫描、Whois查询、DNS查询等。下面是一个简单的Python端口扫描脚本示例:

import socketdef port_scan(ip, port):    s = socket.socket(socket.AF_INET, socket.SOCK_STREAM)    s.settimeout(1)    result = s.connect_ex((ip, port))    s.close()    if result == 0:        return f"{ip}:{port} is open"    else:        return f"{ip}:{port} is closed"

在这个简单的端口扫描示例中,我们使用了Python的socket库来快速进行端口扫描,其中socket.AF_INET表示使用IPv4地址,socket.SOCK_STREAM是指使用TCP协议。

2.漏洞扫描

Python可以通过自己编写扫描程序来实现漏洞扫描,其中常用到的库包括 requests、BeautifulSoup、re 等。以下是一个简单的扫描示例:

import requestsfrom bs4 import BeautifulSoupimport reurl = 'http://www.example.com'r = requests.get(url)soup = BeautifulSoup(r.text, 'html.parser')links = [link.get('href') for link in soup.find_all('a')]for link in links:    if 'javascript' in link or '#' in link:        continue    if link.startswith('/'):        link = url + link    if not link.startswith('http'):        link = 'http://' + link    try:        r = requests.get(link)        if re.search('password', r.text, re.IGNORECASE):            print('vuln found: ', link)    except:        pass

解释如下

1 行:导入 requests 模块,它是用于HTTP请求的 Python 库。import requests第 2 行:从 bs4 模块中导入 BeautifulSoup 类,它是一个用于解析HTML和XML文档的库。from bs4 import BeautifulSoup第 3 行:导入 Python 的正则表达式模块 re。import re第 5 行:定义要爬取的网页的URL地址。url = 'http://www.example.com'6 行:使用 requests.get() 方法向指定的 URL 发送 GET 请求,并将响应结果保存到变量 r 中。r = requests.get(url)7 行:使用 BeautifulSoup 类解析 r.text 中的 HTML 格式内容,并将解析后的结果保存到变量 soup 中。soup = BeautifulSoup(r.text, 'html.parser')8 行:使用列表推导式和 find_all() 方法找到所有标签为 <a> 的元素,然后获取这些元素的链接地址,并将这些链接地址保存到名为 links 的列表中。links = [link.get('href') for link in soup.find_all('a')]当你使用 soup.find_all('a') 时,它将返回 HTML 页面中所有 <a> 标签的列表。在这个列表中,每个元素都是一个 BeautifulSoup 对象,代表一个 <a> 标签。在这个标签对象上,你可以调用 .get('href') 方法来获取该标签的 href 属性的值。现在,我们使用列表推导式 [link.get('href') for link in soup.find_all('a')] 来遍历这个包含多个标签对象的列表,并对每个标签对象执行 link.get('href') 方法,将该标签的 href 属性的值提取出来并添加到一个新列表中。最终,这个新列表将包含页面中所有链接的 URL。因此,这行代码的作用就是获取 HTML 页面中所有链接的 URL,并将它们保存到名为 links 的列表中。第 9-24 行:对 links 列表中的每个链接进行以下操作:    第 10 行:如果链接中包含 "javascript""#",那么跳过本次循环。    第 11-12 行:如果链接以 "/" 开头,那么将其转换为完整的 URL。    第 13-14 行:如果链接既不以 "http" 开头,也不以 "/" 开头,那么将其转换为完整的 URL。    第 15-22 行:向每个链接发送 GET 请求,并检查响应结果的 HTML 内容是否包含单词 "password"(忽略大小写)。如果是,则打印该漏洞链接。    第 23 行:如果出现异常,则直接跳过本次循环。for link in links:    if 'javascript' in link or '#' in link:        continue    if link.startswith('/'):        link = url + link    if not link.startswith('http'):        link = 'http://' + link    try:        r = requests.get(link)        if re.search('password', r.text, re.IGNORECASE):            print('vuln found: ', link)    except:        pass总之,这个 Python 脚本主要是用来扫描网站的漏洞,即检查网站中所有的链接地址,看看有没有泄露密码信息的漏洞。

在上面的示例中,我们使用 requests 和 BeautifulSoup 库获取网页中所有的链接,并逐一进行访问,如果返回结果中存在 password 原始字符串,则视为发现漏洞。

爆破

在渗透测试中,爆破是指使用程序或者工具对密码或者密钥进行暴力破解。Python可以通过编写字典生成器或者调用一些现成的模块来进行爆破。

字典生成器

字典生成器是用于生成密码的一种工具,可以通过Python编写。下面是一个简单的字典生成器示例:

import itertoolsdef generate_dict(chars, length):    """    生成长度为 length 的由 chars 中的字符组成的密码字典    chars: 密码字典的字符列表    length: 生成的密码长度    """    pw_list = []    for i in range(1, length+1):        pw_list += list(itertools.product(chars, repeat=i))    pw_dict = ["".join(item) for item in pw_list]    return pw_dictif __name__ == "__main__":    chars = "abcdefghijklmnopqrstuvwxyz0123456789"    pw_dict = generate_dict(chars, 1)    print(pw_dict)

在上面的示例中,我们使用 itertools.product() 函数生成了一个由 chars 中字符组成的长度为 length 的所有可能情况的元组,然后转换为字符串,并最终生成一个密码字典。

调用现成的模块

在Python中,有许多现成的第三方模块可供使用,例如 requests、selenium、smtplib 等。这些模块中通常已经封装了许多功能,可以帮助渗透测试人员更快速地进行爆破。

爬虫

在网络安全领域,爬虫常被用来获取目标系统的信息。Python可以通过编写程序或者调用现成的爬虫框架来进行爬虫。

编写爬虫程序

Python可以通过第三方库 requests 或者 urllib 来实现网页爬取,下面是一个使用 requests 库实现爬取百度首页的示例:

import requestsurl = 'https://www.baidu.com/'r = requests.get(url)print(r.text)

在上面的示例中,我们使用 requests 库的 get() 方法发送了一个 HTTP GET 请求,获取了百度首页的 HTML 内容,并使用 print() 函数输出了 HTML 内容。

编写多线程高效爬虫

在Python中,还有一些常用的爬虫框架,例如 scrapy、beautifulsoup4、selenium 等。这些框架封装了很多常用的爬虫功能,可以帮助渗透测试人员更快速地进行爬虫。

import threadingimport requestsfrom queue import Queuefrom bs4 import BeautifulSoup    import 关键字用于导入需要使用的库和模块。    threading 是 Python 内置的多线程库,用于创建和管理线程。    requests 是一个流行的 HTTP 请求库,用于发送 HTTP 请求并获取响应。    Queue 是 Python 提供的一个线程安全的队列实现,用于在多个线程之间共享数据。    BeautifulSoup 是一个流行的 HTML 解析库,用于从 HTML 页面中提取数据。# 定义一个线程数THREAD_NUM = 10# 定义一个队列,用来存放要爬取的网页链接url_queue = Queue()    THREAD_NUM 常量存储了线程数,可以根据自己的需求进行修改。    url_queue 变量定义了一个队列对象,用于存储要爬取的链接。def crawl(url_queue):    while not url_queue.empty():        url = url_queue.get()        try:            # 发送请求获取网页内容            response = requests.get(url)            # 解析网页内容            soup = BeautifulSoup(response.text, "html.parser")            title = soup.title.string            print(f"Title: {title} - URL: {url}")        except Exception as e:            print(f"Error occurred when crawling {url}: {e}")    def 关键字用于定义函数。    crawl 函数是一个工作线程的实现,它从队列中取出一个链接并抓取网页数据。    while 循环语句用于不断地从队列中获取链接,直到队列为空。    url_queue.get() 方法从队列中获取下一个链接。    try...except 块用于捕获可能出现的异常,比如网络请求超时或者解析错误等。    requests.get 发送 HTTP 请求并返回响应对象。    BeautifulSoup(response.text, "html.parser") 将响应对象的文本内容作为参数传递给 BeautifulSoup 构造函数,并指定使用 HTML 解析器进行解析。    soup.title.string 获取页面的字符串,即 <title> 标签内的文本内容。    print 函数用于在终端上输出结果。    在Python中,try-except块用于处理异常。在这种情况下,try块内的代码尝试爬取指定的URL。如果发生异常,则控制流跳转到except块,其中捕获异常对象并与相应的错误消息一起打印。if __name__ == '__main__':    # 需要抓取的链接列表    urls = [        "https://www.google.com",        "https://www.bing.com",        "https://www.baidu.com",        "https://www.sogou.com",        "https://www.yahoo.com",        "https://www.duckduckgo.com",        "https://www.ask.com",        "https://www.wolframalpha.com",        "https://www.yandex.ru",        "https://www.dogpile.com"    ]    # 将所有的链接添加到队列中    for url in urls:        url_queue.put(url)    # 创建多个线程并启动    threads = []    for i in range(THREAD_NUM):        t = threading.Thread(target=crawl, args=(url_queue,))        threads.append(t)  # 这行代码使用了Python中的列表append()方法,将一个新的元素t添加到threads列表的末尾。具体地说,t是在前面的循环中创建的Thread对象,它包含了要执行的函数和参数。通过调用append()方法并传入t作为其参数,可以将这个线程对象加入到threads列表中,以便稍后能够遍历所有的线程对象并启动它们。因此,这行代码的作用是将每个创建好的线程对象都添加到一个列表中,以便后续操作。    for t in threads:        t.start()    # 等待所有线程结束    for t in threads:        t.join()部分详细解释如下:    if __name__ == '__main__': 判断当前脚本是否被直接运行,而不是被导入到其他脚本中。    urls 列表存储了需要抓取的链接。首先,创建一个空列表threads,用于存放线程对象。接着,使用一个循环语句创建THREAD_NUM个线程,每个线程都执行crawl函数,并将url_queue作为参数传入。这里使用了Python中的threading.Thread类来创建线程对象,其中target参数指定线程要执行的函数,args参数指定要传递给该函数的参数。将创建好的线程对象依次添加到threads列表中。接下来,再次使用一个循环语句,依次启动所有线程,即调用每个线程对象的start()方法。然后,使用另一个循环语句来等待所有线程结束,即调用每个线程对象的join()方法。这样可以保证在所有线程执行完毕之前,主线程不会退出,从而确保所有线程都能够正常执行完成。    for 循环用于将每个链接添加到队列中。    range(THREAD_NUM) 返回一个从 0 到 THREAD_NUM-1 的整数序列。    threading.Thread 创建了一个新的工作线程对象。    target 参数指定工作线程的执行函数,即 crawl 函数。    args 参数

POC编写

在渗透测试中,编写POC是一种非常重要的技能,可以通过Python编写POC进行漏洞验证、利用等。下面是一个简单的POC示例:

import requestsurl = 'http://www.example.com/vuln.php?id=1'payload = '1\' and 1=1#'r = requests.get(url + payload)if 'vulnerable' in r.text:    print('vulnerable')else:    print('not vulnerable')

在上面的示例中,我们通过构造 payload 参数来构造 SQL 注入漏洞 POC,通过发送 HTTP 请求并解析返回结果进行漏洞验证。

这些是Python在渗透测试中的简单应用,当然还有很多其他的应用场景需要根据实际情况进行编写和实现。

渗透测试框架

在渗透测试中,有许多常用的渗透测试框架,例如 metasploit、beef、armitage 等,这些框架通常都是由多种编程语言(例如Python)组合而成。

以下是一个使用 Python 编写的 metasploit 漏洞验证脚本示例:

import osdef verify(target, port):    os.system(f"msfconsole -x 'use auxiliary/scanner/http/wordpress_xmlrpc_login; set RHOSTS {target}; set RPORT {port}; set STOP_ON_SUCCESS true; run'")

在上面的示例中,我们使用 os 模块调用 metasploit 框架,并通过输入命令实现对 WordPress XML-RPC 登录漏洞的验证。

防御

在渗透测试中,Python也可以用于编写一些防御脚本,例如 IDS(入侵检测系统)和 IPS(入侵防御系统)等。

以下是一个使用 Python 编写的简单 IPS 脚本示例:

import osdef block_ip(ip):    os.system(f'sudo iptables -A INPUT -s {ip} -j DROP')

在上面的示例中,我们可以通过 block_ip 函数实现对指定ip的访问阻断。

这些仅是Python在渗透测试中应用的部分示例,Python的应用场景非常广泛,涉及到的领域也很多。重点的是,我们需要在实际使用中结合实际情况灵活应用Python。

漏洞扫描

漏洞扫描是渗透测试的重要阶段,Python可以用来编写各种漏洞扫描脚本。常用的漏洞扫描脚本包括SQL注入、XSS、文件包含等。以下是一个简单的Python SQL注入检测脚本示例:

import requestsdef sqli_scan(url):    payload = "'"    res = requests.get(url + payload)    if "error in your SQL syntax" in res.text:        return f"{url} is vulnerable to SQL injection"    else:        return f"{url} is not vulnerable to SQL injection"

在这个简单的SQL注入扫描脚本示例中,我们通过构造一个SQL注入的payload,并向目标网站发送请求,检测返回值中是否包含特殊字符,如果包含特殊字符则判断这个网站存在SQL注入漏洞。

端口扫描器

除了渗透测试中的各种应用场景,Python还可以用于开发各种扫描器和利用工具的脚本,例如端口扫描器、Web漏洞扫描器等等。以下是一个简单的Python端口扫描器示例:

import argparseimport threadingimport socket# 解析命令行参数parser = argparse.ArgumentParser(description="Python Port Scanner")parser.add_argument("host", help="Target host")parser.add_argument("-p", "--ports", default="1-1000", help="Target ports (example: 1-1000)")args = parser.parse_args()def scan_port(ip, port):    s = socket.socket(socket.AF_INET, socket.SOCK_STREAM)    s.settimeout(1)    result = s.connect_ex((ip, port))    s.close()    if result == 0:        print(f"{ip}:{port} is open")def scan_ports(ip, ports):    start_port, end_port = ports.split('-')    start_port, end_port = int(start_port), int(end_port)    for port in range(start_port, end_port+1):        t = threading.Thread(target=scan_port, args=(ip, port))        t.start()if __name__ == "__main__":    scan_ports(args.host, args.ports)

在这个端口扫描器示例中,我们通过Python的argparse模块来处理命令行参数,并通过多线程的方式实现了效率更高的端口扫描工具。

数据分析和可视化

Python可以用于数据分析和可视化,可以帮助安全研究人员绘制数据图表以及进行统计分析。以下是一个简单的Python数据可视化示例:

import matplotlib.pyplot as pltx = [1, 2, 3, 4, 5]y = [5, 7, 3, 8, 4]plt.plot(x, y)plt.xlabel("X-axis")plt.ylabel("Y-axis")plt.show()

在这个数据可视化示例中,我们使用matplotlib库将数据以图表的形式展示出来。

代码审计

Python可以用于应用程序和Web应用程序的代码审计,可以快速检测潜在的漏洞和安全问题。以下是一个Python代码审计示例:

import urllib.parseurl = "http://www.example.com/search?q=%3Cscript%3Ealert(%22hello%22)%3C/script%3E"parsed_url = urllib.parse.urlparse(url)params = urllib.parse.parse_qs(parsed_url.query)if "q" in params:    print(f"XSS vulnerability detected: {params['q'][0]}")

在这个简单的代码审计示例中,我们使用Python的urllib.parse库来解析URL,并通过检测URL参数中是否包含特定的字符串,判断可能存在XSS漏洞。

加密和解密

Python可以用于加密和解密数据,例如密码哈希、对称加密算法和非对称加密算法。以下是一个使用Python进行密码哈希的示例:

import hashlibdef sha256_hash(password):    sha256 = hashlib.sha256()    sha256.update(password.encode())    return sha256.hexdigest()password = input("Enter password: ")hashed_password = sha256_hash(password)print(f"Hashed password: {hashed_password}")

在这个简单的密码哈希示例中,我们使用Python的hashlib库来计算SHA256哈希值,并返回16进制字符串格式的哈希结果。

操作系统操作

Python可以用于操作系统的操作,例如文件操作、进程管理和网络配置等。以下是一个简单的Python文件读写示例:

# 写入文件with open("file.txt", "w") as f:    f.write("Hello World!")# 读取文件with open("file.txt", "r") as f:    content = f.read()print(content)

在这个简单的文件读写示例中,我们使用了Python的文件操作函数,包括使用with语句打开文件句柄,然后通过读写操作,最后关闭文件句柄。

总结来说,在渗透测试中,Python有非常广泛的应用和使用场景,包括端口扫描、漏洞扫描、渗透测试框架、防御、脚本开发、数据分析和可视化、代码审计、加密和解密以及操作系统操作等。同时,Python语法的掌握也非常重要,需要掌握Python的函数、条件语句、循环语句、模块和包、外部库等核心语法。

当然,请允许我再介绍一些Python在渗透测试中的应用。

暴力破解

Python可以用于暴力破解攻击,例如密码破解等。以下是一个简单的Python密码破解示例:

import zipfilezip_file = "example.zip"password_list = ["password", "123456", "qwerty"]for password in password_list:    try:        with zipfile.ZipFile(zip_file) as zf:            zf.extractall(pwd=password.encode())        print(f"Password is {password}")        break    except zipfile.BadZipFile:        print(f"Bad zip file: {zip_file}")    except RuntimeError as e:        print(f"Password {password} is not correct: {e}")

在这个密码破解示例中,我们使用了Python的zipfile库来操作ZIP文件,并通过遍历密码列表,尝试破解ZIP文件的密码。

安全编码

Python可以用于编写安全代码,并进行代码安全审计。例如,Python代码中的一些语法问题、不安全的库和函数、不正确的输入验证等都可能导致安全问题。以下是一个简单的Python安全编码示例:

import redef validate_input(input_str):    if not re.match(r"^[A-Za-z0-9_-]+$", input_str):        return False    return True

在这个简单的安全编码示例中,我们使用了Python的re库来进行输入验证,例如检查输入字符串是否只包含数字、字母、下划线和破折号等字符。

恶意代码分析

Python可以用于恶意代码分析,例如利用Python的反汇编、字符串匹配和模式识别工具等来分析和检测恶意代码中的漏洞和行为。以下是一个简单的Python恶意代码分析示例:

import liefbinary = lief.parse("malware.exe")for function in binary.functions:    # 查找包含HTTP请求的函数    if "http://" in function.name or "https://" in function.name:        print(f"Found potential HTTP connection in function: {function.name}")

在这个简单的恶意代码分析示例中,我们使用了Python的lief库来解析PE文件,并通过遍历PE文件中的函数,查找包含HTTP请求的潜在函数。

自动化脚本开发

Python可以用于开发自动化脚本,例如自动化扫描工具、自动化漏洞利用工具等。以下是一个简单的Python自动化脚本开发示例:

import requestsurl = "http://www.example.com/login.php"payload = {    "username": "admin",    "password": "password"}r = requests.post(url, data=payload)if r.status_code == 200 and "Welcome" in r.text:    print("Login success!")else:    print("Login failed.")

在这个简单的自动化脚本开发示例中,我们使用了Python的requests库来进行网络请求,并通过POST方式提交登录表单,最后根据响应状态码和内容判断登录是否成功。

数据库操作

Python可以用于数据库操作,例如连接、查询、修改、删除、创建等。以下是一个简单的Python数据库操作示例:

import sqlite3conn = sqlite3.connect("example.db")# 创建表conn.execute("""CREATE TABLE IF NOT EXISTS users (    id INTEGER PRIMARY KEY AUTOINCREMENT,    name TEXT,    email TEXT);""")# 插入数据conn.execute("INSERT INTO users(name, email) VALUES(?, ?)", ("Alice", "alice@example.com"))# 查询数据for row in conn.execute("SELECT * FROM users"):    print(row)conn.close()

在这个简单的数据库操作示例中,我们使用了Python的sqlite3库连接SQLite数据库,并通过SQL语句创建表、插入数据和查询数据。

来源地址:https://blog.csdn.net/weixin_65527369/article/details/130007179

阅读原文内容投诉

免责声明:

① 本站未注明“稿件来源”的信息均来自网络整理。其文字、图片和音视频稿件的所属权归原作者所有。本站收集整理出于非商业性的教育和科研之目的,并不意味着本站赞同其观点或证实其内容的真实性。仅作为临时的测试数据,供内部测试之用。本站并未授权任何人以任何方式主动获取本站任何信息。

② 本站未注明“稿件来源”的临时测试数据将在测试完成后最终做删除处理。有问题或投稿请发送至: 邮箱/279061341@qq.com QQ/279061341

软考中级精品资料免费领

  • 历年真题答案解析
  • 备考技巧名师总结
  • 高频考点精准押题
  • 2024年上半年信息系统项目管理师第二批次真题及答案解析(完整版)

    难度     813人已做
    查看
  • 【考后总结】2024年5月26日信息系统项目管理师第2批次考情分析

    难度     354人已做
    查看
  • 【考后总结】2024年5月25日信息系统项目管理师第1批次考情分析

    难度     318人已做
    查看
  • 2024年上半年软考高项第一、二批次真题考点汇总(完整版)

    难度     435人已做
    查看
  • 2024年上半年系统架构设计师考试综合知识真题

    难度     224人已做
    查看

相关文章

发现更多好内容

猜你喜欢

AI推送时光机
位置:首页-资讯-后端开发
咦!没有更多了?去看看其它编程学习网 内容吧
首页课程
资料下载
问答资讯