POC编写基础篇


POC的概念


在网络安全领域中,POC的概念是指"Proof of Concept",也被称为"攻击验证"。它是指安全研究人员或黑客用来证明某个漏洞、弱点或安全问题存在的实证或演示。
网络安全研究人员经常通过开发POC来展示一个漏洞的存在和影响,从而向厂商或用户提供证据,并促使其采取必要的措施来修复或解决该问题。通过POC,研究人员可以演示如何利用漏洞来进行攻击、获取敏感信息或者破坏系统。
POC通常包括漏洞的利用代码、相关的技术细节以及攻击成功的证据。通过POC,安全研究人员可以向厂商或组织提供一个具体的案例,以加强对漏洞的重要性和紧迫性的认识,并促使其采取适当的补救措施。

简单理解就是:POC就是用来验证某个漏洞是否存在的一段代码。

POC 的编写流程


1、理解漏洞产生的原理
获取一个漏洞的详细情况后,确定影响范围。

2、漏洞环境搭建
通过官网下载受影响版本,搭建复现环境。或者使用现成的漏洞复现环境,如vulfocus.cn、vulhub,对应一些无害的漏洞,可以使用fofa 找对应版本环境进行复现。
3、漏洞复现
根据漏洞详情,检测漏洞是否存在,其中要尤其注意些参数、命令、函数及对应的提交方法,大概了解漏洞的原理、利用过程、判断漏洞是否存在的地方。方便在写poc 的时候对其进行匹配规则。
4、创建POC脚本
使用 python 写一个 http 请求模拟浏览器,替换上POC
5、发起漏洞验证请求(POC测试)
poc测试,这里有时候需要进行调试,可以配合burpsuite 进行调试。从响应中去找唯一的特征进行匹配是否存在漏洞。可以一个或者多个,主要更具漏洞情况而定。

POC编写流程演示

从0到1—POC编写基础篇(一)-LMLPHP

这里以jeecgBoot 前台SQL注入漏洞(CVE-2023-1454)为例
1、理解漏洞产生的原理
jeecg-boot 3.5.0 版本存在SQL注入漏洞,该漏洞源于文件 jmreport/qurestSql 存在安全问题, 通过参数 apiSelectId 导致SQL注入。影响范围 jeecg-boot 3.5.0版本。

2、漏洞环境搭建
这里直接使用fofa 环境进行演示

从0到1—POC编写基础篇(一)-LMLPHP

3、漏洞复现


使用poc,验证成功,存在该目标存在注入漏洞。这里可以观察响应包的状态、返回值、返回参数等。

从0到1—POC编写基础篇(一)-LMLPHP

4、创建POC脚本


使用 python 写一个 http 请求模拟浏览器,替换上POC,如URL、提交数据、提交方式

从0到1—POC编写基础篇(一)-LMLPHP

5、发起漏洞验证请求(POC测试)
这里有时候需要进行调试,去匹配结果。可以输出结果,也可以配合burpsuite 进行调试。

从0到1—POC编写基础篇(一)-LMLPHP

从响应中去找唯一的特征进行匹配是否存在漏洞。可以一个或者多个,主要更具漏洞情况而定。

从0到1—POC编写基础篇(一)-LMLPHP

POC编写基础知识


Python 中的循环函数


python 中有多个循环函数,这个在写poc 中常用到的则是for循环函数。
for 循环
for 循环是 Python 中最常用的循环方式之一,它可以对序列元素进行迭代。序列可以是一个列表、元组、字符串等。在poc 脚本中,经常会遇到使用多个payload进行拼接url进行多次请求。
示例:

for payload in payloads:
    print(payload)

# 迭代字符串中的字符
text = 'hello world'
for char in text:
    print(char)

# 在 for 循环中使用 range() 函数
for i in range(3):
      print(i)

Python中对文本的读写


我们使用poc脚本批量对目标进行测试的时候,通常会把存在漏洞的目标保存起来,此时就会用到pythond 读写功能了。
1、打开文件
Python 中打开文件的函数是 open(),它可接受一个文件名和打开模式作为参数,返回一个文件对象。
打开模式包括:

●"r":只读模式(默认)。    
●"w":写入模式,会覆盖原有内容。    
●"x":独占写入模式,如果文件已存在则会引发 FileExistsError 异常。    
●"a":追加模式,会在文件尾部添加新内容。    
●"b":二进制模式。    
●"t":文本模式(默认)。    
●"+":在原有功能基础上增加读写模式。

# 以只读模式打开文件
 file = open("test.txt", "r")

2、读取文件内容


读取文件内容的方法包括 read()、readline() 和 readlines()。
●read() 函数用于读取整个文件的内容,返回一个字符串。
●readline() 函数用于读取文件的一行内容,返回一个字符串。
●readlines() 函数用于读取文件的所有行,返回一个包含所有行的列表。
使用示例:

# 以只读模式打开文件
 file = open("test.txt", "r")
 # 读取整个文件内容
 content = file.read()
 print(content)
 # 读取一行内容
 line = file.readline()
 print(line)
 # 读取所有行
 lines = file.readlines()
 print(lines)

3、写入文件


写入文件的操作通常是在只写模式下打开文件,并使用 write() 函数向文件中写入内容。
使用示例:

# 以写入模式打开文件
 file = open("output.txt", "w")
 # 写入内容
 file.write("This is the first line.\n")
 file.write("This is the second line.\n")
 # 关闭文件
 file.close()

4、追加内容到文件


使用追加模式打开文件后,可以使用 write() 函数将内容追加到文件末尾。
使用示例:

# 以追加模式打开文件
 file = open("test.txt", "a")
 # 在文件尾部追加内容
 file.write("This is test\n")
 # 关闭文件
 file.close()

5、关闭文件


使用完打开的文件后,需要使用 close() 函数来关闭文件,以释放系统资源。
使用示例:

# 打开文件
 file = open("test.txt", "r")
 # ... 一些读写操作 ...
 # 关闭文件
 file.close()

6、功能实现


写一个保存目标结果的函数

def write(urlpath):
    curr_dir = os.getcwd()
    vuln_file = '/vuln_' + datetime.now().date().strftime('%Y%m%d') + '.txt'
    f = open(curr_dir + vuln_file, 'a+', encoding='utf-8')
    f.write("漏洞存在:%s " % urlpath + "\r")
    f.close()

写一个批量读取的函数

def write(url):
	with open(url, "r", encoding="utf-8") as file:
    for line in file:
          url = line.strip()
          poc()

从0到1—POC编写基础篇(一)-LMLPHP

Python中对URL处理


如果一大堆目标没有统一的格式的时候,则需要对url 进行统一处理
url处理包括:识别url前缀,没有http&https的添加http或者https删除url路径部分url结尾有/ 则去掉/

import sys
def process_url(url):
    # 添加http或https前缀
    if not url.startswith('http://') and not url.startswith('https://'):
        url = 'http://' + url

    # 删除URL路径部分
    url_parts = url.split('/')
    url_without_path = '/'.join(url_parts[:3])

    # 去掉URL末尾的斜杠
    if url_without_path.endswith('/'):
        url_without_path = url_without_path[:-1]

    return url_without_path


# 主函数
if __name__ == "__main__":
    url = sys.argv[1]
    processed_url = process_url(url)
    print("处理后的URL:", processed_url)

从0到1—POC编写基础篇(一)-LMLPHP

Python中对文本内容去重


使用set 集合对文件内容进行去重

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

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')
04-24 08:11