1. Vulnhuntr工作流程图
严禁盗传


2. 解析
① 预处理/初始化阶段
Vulnhuntr首先会根据我们指定的路径,判断是否network_related,如相关,则根据定义好的pattern来识别不同web框架。Vulnhuntr只支持python语言漏洞检测,所以这些都是python web框架如flask和django等。如下图所示:

得到所有待分析的python文件后,Vulnhuntr开始初始化LLM,LLM可以选取GPT/Claude/Ollama本地部署模型。初始化LLM利用了构建的system prompt,由README Summary和预定义好的Instruction组成。
Vulnhuntr还会读取文件内容content并写入FileCode数组中。
② 第一次分析
如图所示,无论是第一次分析还是第二次分析,我们都是通过LLM.chat()类方法进行分析并获取结果的。
在第一次分析中,我们将给模型提供Response Format,Guidelines,Previous Analysis,Analysis Approach,Instructions,FileCode作为prompt给模型。需要注意的是这些内容都以xml格式提供给了模型。各部分内容的意义在图可见。
第一次分析的结果是粗略的。在这次分析中,模型会给出所有可能的漏洞类型,并且会给出模型认为需要进一步分析请求的上下文。简单来说,模型在分析中会发现代码内容的某些部分需要进行进一步研究,于是就把这些部分写入context_code,而我们会在第二次分析中关注context_code所关联的函数或类等的定义,调用静态分析库Jedi来获取其定义和描述,并提供给模型做参考。
③ 第二次分析
第二次分析进行的前提是第一次分析可以分析出一点漏洞的蛛丝马迹。如果第一次分析发现没有可能存在漏洞,那么是不会进行第二次分析的。
第二次分析实际上是一个迭代过程,在Vulnhuntr代码中,迭代上限轮数定义为7轮。同时,第二次分析是对第一轮分析得出的所有潜在漏洞都进行至高7次的迭代。也就是说,若第一次分析发现了SQL注入漏洞和XSS漏洞两种漏洞,则各进行最高7次的漏洞。
我们需要关注迭代的停机条件。如图所示,停机条件除了迭代次数达到定义的上限以外,Vulnhuntr更需要关注的是上一次迭代时的模型输出,查看模型是否认为有进一步研究的空间。如果没有,自然就停止了迭代。
前面提到,Vulnhuntr的分析都是基于模型对话的,因此第二次分析也是依靠prompt的构建。在第二轮分析中,例如Response Format,Guidelines,Analysis Approach和FileCode,都和第一轮分析没有任何区别。下面我们着重关注一下有变更的部分:
- Previous Analysis:这记录了上一次的报告的分析内容。在之前的第一次分析中,这部分就是空的,而在第二次分析阶段中,除了第一轮迭代外,后续轮次的迭代都是有内容的。可能的疑问是,第二次分析的首轮迭代中,提供给模型的previous analysis不应该是第一次分析的报告嘛?但实际我们需要关注两次分析的目的,正如最开始就提到的,第一次分析的目的是粗略的抓住可能的所有漏洞,和第二次分析这种对于某种特定漏洞展开的进一步分析时不同的。因此,第二次首轮迭代中previous analysis依旧为空。需要注意的是,previous analysis在后续迭代是覆盖的,而不是append进去。这表明迭代的目的就是递进分析。
- definitions:这是模型此前分析中的context_code相关的函数或类的定义与描述,由静态分析库Jedi生成。Jedi是Python内置的静态分析库。至于definitions具体是如何生成的,可以看上面黄色便签内的流程图。
- Example Bypasses:提供某种漏洞的绕过机制示例,从而有助于模型给出poc。
- Instructions:提供了某种漏洞的高危函数等介绍信息,有助于模型对特定漏洞做进一步分析。
④ 分析报告写入日志文件
可以在下面的示例中查看日志文件的格式与内容。
3. 关于项目的运行
parser = argparse.ArgumentParser(description='Analyze a GitHub project for vulnerabilities.Export your ANTHROPIC_API_KEY/OPENAI_API_KEY before running.')
parser.add_argument('-r', '--root', type=str, default='F:\\Code_Learning\\vulnhuntr-main\\sqlvul.py', required=False, help='Path to the root directory of the project')
parser.add_argument('-a', '--analyze', type=str, help='Specific path or file within the project to analyze')
parser.add_argument('-l', '--llm', type=str, choices=['claude', 'gpt', 'ollama'], default='gpt', help='LLM client to use (default: gpt)')
parser.add_argument('-v', '--verbosity', action='count', default=0, help='Increase output verbosity (-v for INFO, -vv for DEBUG)')
args = parser.parse_args()
Vulnhuntr是基于CLI的,需要在命令行给出命令:
- -r:检测路径
- -a:启动分析
- -l:模型选择
- -v:控制输出详细程度
4. 示例
我在F:\Code_Learning\vulnhuntr-main下设置了一个简单sqlvul.py,接下来将用Vulnhuntr检测这个sql注入漏洞
① 运行命令
F:\Code_Learning\vulnhuntr-main> vulnhuntr -r "F:\Code_Learning\vulnhuntr-main" -a "sqlvul.py" -l gpt -v
项目启动,如下图所示:

相关内容都写入了log中,如下图所示:

② 查看分析内容
看一下Vulnhuntr的分析,为了方便阅读,我分块贴入。
a. 第一次分析
scratchpad
- The code imports sqlite3 and establishes a connection to a SQLite database.
- The user input is directly interpolated into the SQL query string without any sanitization. This can lead to potential SQL Injection vulnerabilities.
- The query is executed, fetching results for the given user input.
- No explicit security controls or sanitization measures are implemented to prevent SQL Injection.
- The code lacks input validation and is vulnerable to SQL Injection attacks due to the concatenation of user input into the SQL query.
翻译一下:
- 这段代码导入了
sqlite3模块,并建立了与 SQLite 数据库的连接。 - 用户输入在没有经过任何净化处理的情况下直接被插入到 SQL 查询字符串中。这可能会导致潜在的 SQL 注入漏洞。
- 执行该查询,获取针对给定用户输入的查询结果。
- 没有实施任何明确的安全控制或净化措施来防止 SQL 注入。
- 由于将用户输入连接到 SQL 查询中,这段代码缺乏输入验证,容易受到 SQL 注入攻击。
analysis
The code provided is vulnerable to SQL Injection due to directly embedding user input into the SQL query string. An attacker could manipulate the ‘user_input’ variable to execute arbitrary SQL commands, potentially leading to data theft, modification, or deletion. The lack of input validation and sanitization makes it a high-risk vulnerability. Since the vulnerability stems from SQL Injection, the confidence score for this finding is 9 out of 10.
翻译一下:
由于代码直接将用户输入嵌入到SQL查询字符串中,因此存在SQL注入漏洞。攻击者可以操纵user_input变量来执行任意SQL命令,这可能会导致数据被盗取、修改或删除。由于缺乏输入验证和数据清理,该漏洞的风险等级较高。鉴于此漏洞源于SQL注入,此发现的置信度评分为9分(满分10分)。
poc
To exploit the SQL Injection vulnerability, an attacker can input ‘admin’; DROP TABLE users; --’ as the user_input. This input would result in a SQL query that drops the ‘users’ table, demonstrating the impact of the vulnerability.
翻译一下:
为了利用这个SQL注入漏洞,攻击者可以输入 'admin'; DROP TABLE users; -- 作为用户输入。这样的输入会使生成的SQL查询执行删除 users 表的操作,这充分体现了该漏洞可能造成的严重影响。
confidence_score
9
vulnerability_types:
VulnType.SQLI
context_code:
空的
b. 第二次分析
scratchpad
- The code in the provided file accepts user input in the ‘user_input’ variable. The input value seems to be directly concatenated into the SQL query without any sanitization or parameterization.
- The user input ‘admin’; DROP TABLE users; --’ is a classic example of SQL Injection attempt with malicious intent to drop the ‘users’ table from the database. This input can lead to a serious security risk if not properly handled.
- SQL queries are being constructed using string formatting with user input, making it vulnerable to SQL Injection attacks.
- There are no visible security controls like input validation or parameterized queries to prevent SQL Injection.
翻译一下:
- 所提供文件中的代码通过
user_input变量接收用户输入。输入值似乎未经任何净化处理或参数化处理,就直接被拼接到SQL查询中。 - 用户输入
'admin'; DROP TABLE users; --是一个典型的SQL注入尝试示例,其恶意目的是从数据库中删除users表。如果处理不当,这样的输入会带来严重的安全风险。 - SQL查询使用字符串格式化并结合用户输入来构建,这使其容易受到SQL注入攻击。
- 代码中没有可见的安全控制措施,如输入验证或参数化查询,来防止SQL注入。
analysis
The provided code is vulnerable to SQL Injection (SQLI) due to the lack of input sanitization and direct concatenation of user input into SQL queries. An attacker could potentially manipulate the input to execute arbitrary SQL commands, such as dropping tables or retrieving unauthorized data. The impact of successful exploitation could result in data loss or exposure of sensitive information.
翻译一下:
由于缺乏输入数据清理,且直接将用户输入拼接到SQL查询中,所提供的代码存在SQL注入(SQLI)漏洞。攻击者可能会操纵输入内容,以执行任意SQL命令,比如删除数据库表或获取未授权的数据。若攻击成功,可能会导致数据丢失或敏感信息泄露。
poc
If the user input is ‘admin’; DROP TABLE users; --’, it could result in dropping the ‘users’ table from the database. Proof of concept exploit: user_input = 'admin'; DROP TABLE users; --'
翻译一下:
如果用户输入为 'admin'; DROP TABLE users; --,这可能会导致从数据库中删除 users 表。概念验证性的攻击示例如下:将 user_input 赋值为 'admin'; DROP TABLE users; --
confidence_score
8
vulnerability_types
VulnType.SQLI
context_code:
空的
③ 讨论一下
可以看出来第二次分析只进行了一轮迭代。在第一次分析中,context_code就是空的了,但是它为空依旧会进行第二次分析。在第二次分析中,如果某轮迭代之后context_code为空,那么才会导致不进入下一轮迭代。因此,最少肯定也进行了两次分析(第一次分析+第二次分析的第一轮迭代)。这是很合理的,因为第二次分析和第一次分析的目标就不同,无论如何第二次分析也应该进行一轮。