POC 指 Proof of Concept(概念验证),是指一个可行性验证,即通过构建一个小型系统或单项功能来验证技术的可行性和正确性。POC 脚本,就是为了验证特定安全漏洞或安全问题而编写的脚本,可用于检测该漏洞是否存在,以及漏洞的利用方式和危害范围。
POC 脚本的编写意义在于:
检测漏洞
POC 脚本可以帮助安全研究人员快速、简便地检测漏洞,而不需要手动去复现漏洞,减轻了工作难度。
确认漏洞可利用性
POC 脚本可以验证漏洞的利用方式和危害范围,帮助安全研究人员更好地了解漏洞对系统的影响,从而更好地为漏洞修复提供技术支持。
辅助漏洞修复
POC 脚本可以给系统管理员提供一个检验漏洞修复效果的工具,验证漏洞是否已经被修复,避免出现漏洞被遗漏的情况。
推动安全产品的发展
POC 脚本能够验证安全产品的性能和效果,提高产品的质量和服务。
因此,POC 脚本的编写是安全研究人员、安全工程师以及系统管理员进行系统安全检测、漏洞检测的必备工具之一,也是安全领域技术发展的重要一环。
for 循环
for 循环是 Python 中最常用的循环方式之一,它可以对序列元素进行迭代。序列可以是一个列表、元组、字符串等。
示例:
# 迭代列表元素
names = ['Alice', 'Bob', 'Charlie']
for name in names:
print(name)
# 迭代字符串中的字符
text = 'hello world'
for char in text:
print(char)
# 在 for 循环中使用 range() 函数
for i in range(5):
print(i)
while 循环
while 循环用于在条件满足时重复执行一段代码。通常在需要等待某些事件发生和数据处理等情况下使用。
示例:
# 使用 while 循环计算 1-10 的累加和
sum = 0
i = 1
while i <= 10:
sum += i
i += 1
print(sum)
range() 函数
range() 函数用于生成一个指定区间内的整数序列。
示例:
# 生成 1-5 的整数序列
for i in range(1, 6):
print(i)
re.match 函数
re.match(pattern, string, flags=0) 函数用于匹配字符串的开头是否符合指定的正则表达式模式。它从字符串的开头开始匹配,如果匹配成功,就返回一个 Match 对象,否则返回 None。
参数解释:
pattern:表示正则表达式模式的字符串。
string:表示要匹配的字符串。
flags:表示正则表达式的匹配标志,可选参数,默认值为 0。
使用示例:
import re
text = 'hello, world!'
pattern = r'^h.*?d!'
match = re.match(pattern, text)
if match:
print(match.group())
输出结果为:
hello, w
re.search 函数
re.search(pattern, string, flags=0) 函数用于在字符串中查找符合正则表达式模式的子串,如果找到,就返回一个 Match 对象,否则返回 None。
参数解释:
pattern:表示正则表达式模式的字符串。
string:表示要查找的字符串。
flags:表示正则表达式的匹配标志,可选参数,默认值为 0。
使用示例:
import re
text = 'hello, world!'
pattern = r'w.*?d'
match = re.search(pattern, text)
if match:
print(match.group())
输出结果为:
world
re.findall 函数
re.findall(pattern, string, flags=0) 函数用于在字符串中查找符合正则表达式模式的所有子串,并以列表的形式返回结果。
参数解释:
pattern:表示正则表达式模式的字符串。
string:表示要查找的字符串。
flags:表示正则表达式的匹配标志,可选参数,默认值为 0。
使用示例:
import re
text = 'Hello, world!'
pattern = r'[a-z]+'
matches = re.findall(pattern, text, re.IGNORECASE)
print(matches)
输出结果为:
['Hello', 'world']
re.finditer 函数
re.finditer(pattern, string, flags=0) 函数用于在字符串中查找符合正则表达式模式的所有子串,并以迭代器的形式返回结果,可以逐个遍历迭代器中的匹配结果。
参数解释:
pattern:表示正则表达式模式的字符串。
string:表示要查找的字符串。
flags:表示正则表达式的匹配标志,可选参数,默认值为 0。
使用示例:
import re
text = 'Hello, world!'
pattern = r'[a-z]+'
for match in re.finditer(pattern, text, re.IGNORECASE):
print(match.group())
输出结果为:
Hello
world
re.split 函数
re.split(pattern, string, maxsplit=0, flags=0) 函数用于根据正则表达式模式的匹配结果分割字符串,并以列表形式返回分割后的子串。
参数解释:
pattern:表示正则表达式模式的字符串。
string:表示要分割的字符串。
maxsplit:表示最大分割次数,可选参数,默认值为 0,表示分割所有匹配结果。
flags:表示正则表达式的匹配标志,可选参数,默认值为 0。
使用示例:
import re
text = 'Hello, world!'
pattern = r'[, ]+'
result = re.split(pattern, text)
print(result)
输出结果为:
['Hello', 'world!']
re.sub 函数
re.sub(pattern, repl, string, count=0, flags=0) 函数用于在字符串中查找并替换所有符合正则表达式模式的子串,然后返回替换后的字符串。
参数解释:
pattern:表示正则表达式模式的字符串。
repl:表示替换的字符串或者函数。
string:表示要查找和替换的原始字符串。
count:表示最大替换次数,可选参数,默认值为 0,表示替换所有匹配结果。
flags:表示正则表达式的匹配标志,可选参数,默认值为 0。
使用示例:
import re
text = 'I like Python!'
pattern = r'Python'
replacement = 'Java'
new_text = re.sub(pattern, replacement, text)
print(new_text)
输出结果为:
I like Java!
打开文件
Python 中打开文件的函数是 open(),它可接受一个文件名和打开模式作为参数,返回一个文件对象。
打开模式包括:
"r":只读模式(默认)。
"w":写入模式,会覆盖原有内容。
"x":独占写入模式,如果文件已存在则会引发 FileExistsError 异常。
"a":追加模式,会在文件尾部添加新内容。
"b":二进制模式。
"t":文本模式(默认)。
"+":在原有功能基础上增加读写模式。
使用示例:
# 以只读模式打开文件
file = open("example.txt", "r")
读取文件内容
读取文件内容的方法包括 read()、readline() 和 readlines()。
read() 函数用于读取整个文件的内容,返回一个字符串。
readline() 函数用于读取文件的一行内容,返回一个字符串。
readlines() 函数用于读取文件的所有行,返回一个包含所有行的列表。
使用示例:
# 以只读模式打开文件
file = open("example.txt", "r")
# 读取整个文件内容
content = file.read()
print(content)
# 读取一行内容
line = file.readline()
print(line)
# 读取所有行
lines = file.readlines()
print(lines)
写入文件
写入文件的操作通常是在只写模式下打开文件,并使用 write() 函数向文件中写入内容。
使用示例:
# 以写入模式打开文件
file = open("output.txt", "w")
# 写入内容
file.write("This is the first line.\n")
file.write("This is the second line.\n")
# 关闭文件
file.close()
追加内容到文件
使用追加模式打开文件后,可以使用 write() 函数将内容追加到文件末尾。
使用示例:
# 以追加模式打开文件
file = open("output.txt", "a")
# 在文件尾部追加内容
file.write("This is the third line.\n")
# 关闭文件
file.close()
关闭文件
使用完打开的文件后,需要使用 close() 函数来关闭文件,以释放系统资源。
使用示例:
# 打开文件
file = open("example.txt", "r")
# ... 一些读写操作 ...
# 关闭文件
file.close()
requests
requests 是 Python 中一个广泛使用的 HTTP 库,用于发送 HTTP
import requests
# 发送 GET 请求
response = requests.get('https://www.baidu.com')
print(response.status_code)
print(response.text)
# 发送 POST 请求
data = {'username': 'admin', 'password': '123456'}
response = requests.post('https://www.example.com/login', data=data)
print(response.status_code)
BeautifulSoup
BeautifulSoup 是一个 Python 第三方库,用于解析 HTML 和 XML 文档。可以使用它来遍历、搜索和修改文档,并提取所需的信息。
示例:
from bs4 import BeautifulSoup
html = """
这是一个标题
这是一个段落。
这是一个链接
"""
# 创建 BeautifulSoup 对象
soup = BeautifulSoup(html, 'html.parser')
# 选取元素
title = soup.title
p = soup.select_one('p.content')
a = soup.select_one('a[href="https://www.example.com"]')
# 获取元素属性
print(title.text)
print(p.text)
print(a['href'])
json
json 是 Python 中用于处理 JSON 格式的模块,可以将 JSON 格式的数据转化为 Python 对象,或将 Python 对象转化为 JSON 格式。
示例:
import json
# 将 Python 对象转化为 JSON 格式
dict_data = {'name': 'Jack', 'age': 20}
json_data = json.dumps(dict_data)
print(json_data)
#将 JSON 格式转化为 Python 对象
json_str = '{"name": "Jack", "age": 20}'
dict_obj = json.loads(json_str)
print(dict_obj['name'])
import requests
# 从文件中读取 URL 列表,每个 URL 单独占一行
def read_file(file):
with open(file, 'r') as f:
data = f.read().splitlines()
return data
# 判断 URL 是否存活
def is_alive(url):
try:
req = requests.get(url, timeout=3)
if req.status_code == 200:
return True
else:
return False
except:
return False
# 批量检测 URL 存活性
def check_url_alive(file):
urls = read_file(file)
result = {}
for url in urls:
if is_alive(url):
result[url] = 'alive'
else:
result[url] = 'dead'
return result
# 测试代码
result = check_url_alive('urls.txt')
for url, status in result.items():
print(url, status)
上述代码中,read_file
函数从文件中读取 URL 列表,每个 URL 单独占一行。is_alive
函数用于判断 URL 是否存活,实现方式与之前的单个 URL 检测一致。check_url_alive
函数调用 read_file
函数读取 URLs 列表,使用 for
循环分别调用 is_alive
函数检测每个 URL 是否存活,并将结果保存在 result
字典中。
最后,测试代码调用 check_url_alive
函数检测 urls.txt
文件中的 URL 存活性,并打印每个 URL 的状态。需要注意的是,urls.txt
文件需要与代码在同一目录下。
https:\\
:def add_prefix(file):
with open(file, 'r') as f:
lines = f.read().splitlines()
for i in range(len(lines)):
lines[i] = 'https:\\' + lines[i]
with open(file, 'w') as f:
for line in lines:
f.write(line + '\n')
# 测试代码
add_prefix('data.txt')
上述代码中,add_prefix
函数接受一个文件名参数,使用 open
函数读取文件内容,并使用 splitlines
方法将文件内容拆分成行列表 lines
。接下来,使用 for
循环遍历每一行,并在每行开头添加 https:\\
。最后,将修改后的行列表写回到同一文件中。
https:\\
:def remove_prefix(file):
with open(file, 'r') as f:
lines = f.read().splitlines()
for i in range(len(lines)):
if lines[i].startswith('https:\\'):
lines[i] = lines[i][8:]
with open(file, 'w') as f:
for line in lines:
f.write(line + '\n')
# 测试代码
remove_prefix('data.txt')
上述代码中,remove_prefix
函数接受一个文件名参数,使用 open
函数读取文件内容,并使用 splitlines
方法将文件内容拆分成行列表 lines
。接下来,使用 for
循环遍历每一行,如果该行以 https:\\
开头,则将该行的前 8 个字符(即 https:\\
)删除。最后,将修改后的行列表写回到同一文件中。
def remove_duplicate(file):
with open(file, 'r') as f:
lines = f.read().splitlines()
lines = set(lines)
with open(file, 'w') as f:
for line in lines:
f.write(line + '\n')
# 测试代码
remove_duplicate('data.txt')
上述代码中,remove_duplicate
函数接受一个文件名参数,使用 open
函数读取文件内容,去重后将结果保存在同一文件中,并覆盖原有内容。具体实现过程如下:
使用 with open
语句打开文件,并将每一行读取到 lines
列表中。
将 lines
列表转换成 Python 中的集合(set),这会自动去除列表中的重复元素。
再次使用 with open
语句打开同一文件,并使用 for
循环将去重后的每一行写入文件中。
需要注意的是,该脚本将原始文件覆盖,因此需要在使用前备份原始文件。如果需要对原始文件内容进行去重而不改变原文件,可以将第一个 with open
语句改为复制文件并返回副本,然后对副本进行去重操作,并将去重后的文本写入新文件中。
import requests
from bs4 import BeautifulSoup
def baidu_search(keyword, n=10):
url = "https://www.baidu.com/s"
headers = {
'User-Agent': 'Mozilla/5.0 (Macintosh; Intel Mac OS X 10_15_0) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/78.0.3904.97 Safari/537.36'}
params = {"wd": keyword, "pn": 0, "rn": n}
response = requests.get(url, headers=headers, params=params)
soup = BeautifulSoup(response.text, "html.parser")
results = []
for i, res in enumerate(soup.select('div.c-container')):
link = res.select_one('h3.t > a')
desc = res.select_one('div.c-abstract')
if link is not None and desc is not None:
title = link.text.strip()
url = link['href']
desc = desc.text.strip()
results.append((i+1, title, url, desc))
return results
# 测试代码
keyword = 'python'
results = baidu_search(keyword, n=10)
for res in results:
print(f'{res[0]}. {res[1]}: {res[3]} ({res[2]})')
上述代码中,baidu_search
函数接受两个参数:keyword
是要搜索的关键词;n
是要返回的搜索结果数量,默认为 10。在函数内部,首先定义了百度搜索的 URL 和请求头部信息,并以 params
字典的形式传递了搜索关键词和结果数量。然后使用 requests
库进行 GET 请求,将结果转化为 BeautifulSoup 对象,通过 CSS 选择器选取搜索结果中的标题、链接和描述,并将结果保存在 results
列表中。最后将结果输出。
需要注意的是,此脚本只是一个示例,它并不考虑反爬虫机制和搜索结果的准确性。在实际应用中,需要根据需要修改请求头、参数和选择器等。
import requests
import json
def fofa_crawler(email, key, query):
url = 'https://fofa.so/api/v1/search/all'
headers = {
'User-Agent': 'Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/58.0.3029.110 Safari/537.3',
'email': email,
'key': key
}
data = {
'qbase64': query,
'size': 100
}
try:
response = requests.post(url, headers=headers, data=data)
if response.status_code == 200:
results = json.loads(response.text)['results']
for result in results:
print(result[0])
else:
print('FOFA 查询失败:{}'.format(response.status_code))
except Exception as e:
print('程序出错:{}'.format(e))
# 测试代码
email = 'your_email'
key = 'your_key'
query = 'domain="example.com" && ip="1.1.1.1/24"'
fofa_crawler(email, key, query)
上述代码中,fofa_crawler
函数接受三个参数:email
是你的 FOFA 账户邮箱地址;key
是你的 API Key,可以在个人中心页面中获取;query
是你要查询的 FOFA 搜索语法。
在函数内部,首先定义了 FOFA 的 API 地址和请求头部信息,并以 data
字典的形式传递了查询语句和结果数量;然后使用 requests
库进行 POST 请求,将查询结果转化为 JSON 格式,并遍历所有结果。最后,将获取到的 IP 地址输出。
需要注意的是,FOFA API 每个月有查询次数限制,超出限制后需要升级会员或等待下个月重新计算。另外,程序中的查询语法 query
也需要根据自己的需要进行修改。