一篇文章教你学如何编写poc

POC 指 Proof of Concept(概念验证),是指一个可行性验证,即通过构建一个小型系统或单项功能来验证技术的可行性和正确性。POC 脚本,就是为了验证特定安全漏洞或安全问题而编写的脚本,可用于检测该漏洞是否存在,以及漏洞的利用方式和危害范围。

POC 脚本的编写意义在于:

检测漏洞

POC 脚本可以帮助安全研究人员快速、简便地检测漏洞,而不需要手动去复现漏洞,减轻了工作难度。

确认漏洞可利用性

POC 脚本可以验证漏洞的利用方式和危害范围,帮助安全研究人员更好地了解漏洞对系统的影响,从而更好地为漏洞修复提供技术支持。

辅助漏洞修复

POC 脚本可以给系统管理员提供一个检验漏洞修复效果的工具,验证漏洞是否已经被修复,避免出现漏洞被遗漏的情况。

推动安全产品的发展

POC 脚本能够验证安全产品的性能和效果,提高产品的质量和服务。

因此,POC 脚本的编写是安全研究人员、安全工程师以及系统管理员进行系统安全检测、漏洞检测的必备工具之一,也是安全领域技术发展的重要一环。

基础知识讲解

Python 中的循环函数

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)

Python 中常用的正则函数库

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中对文本的读写

打开文件

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()

Python 中常用的爬虫函数库

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 = """
 <html>
 <head><title>这是一个标题</title></head>
 <body>
 <p class="content">这是一个段落。</p>
 <a href="https://www.example.com">这是一个链接</a>
 </body>
 </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'])

实战篇

利用Python对网站进行批量存活检测​

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 文件需要与代码在同一目录下。

利用Python在文内内每一行开头添加 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:\\。最后,将修改后的行列表写回到同一文件中。

利用Python删除文本内每一行开头 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:\\)删除。最后,将修改后的行列表写回到同一文件中。

利用Python对文本内容去重

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 函数读取文件内容,去重后将结果保存在同一文件中,并覆盖原有内容。具体实现过程如下:

  1. 使用 with open 语句打开文件,并将每一行读取到 lines 列表中。

  2. lines 列表转换成 Python 中的集合(set),这会自动去除列表中的重复元素。

  3. 再次使用 with open 语句打开同一文件,并使用 for 循环将去重后的每一行写入文件中。

需要注意的是,该脚本将原始文件覆盖,因此需要在使用前备份原始文件。如果需要对原始文件内容进行去重而不改变原文件,可以将第一个 with open 语句改为复制文件并返回副本,然后对副本进行去重操作,并将去重后的文本写入新文件中。

利用Python从百度搜索结果中获取指定关键词的链接和描述

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 列表中。最后将结果输出。

需要注意的是,此脚本只是一个示例,它并不考虑反爬虫机制和搜索结果的准确性。在实际应用中,需要根据需要修改请求头、参数和选择器等。

利用Python从FOFA结果中获取IP地址

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 也需要根据自己的需要进行修改。

  • 5
    点赞
  • 39
    收藏
    觉得还不错? 一键收藏
  • 1
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值