漏扫poc编写(一)

漏洞扫描工具

本篇文章主要讲了afrog,nuclei漏扫工具的使用和对afrog和nuclei的poc的yml文件的编写规则。

afrog下载地址:https://github.com/zan8in/afrog

nuclei下载地址:https://github.com/projectdiscovery/nuclei

afrog

基本使用

1.扫描单个url

1
./afrog -t URL

2.扫描多个url

1
./afrog -T file

3.指定漏扫报告文件(默认html文件输出)

1
./afrog -t url -o result.html

4.显示漏洞列表

1
./afrog -pl

image-20250502192822642

按照某个漏洞搜索【展示】

1
./afrog -s tomcat -pl

image-20250502192920850

5.指定某个漏洞进行扫描【poc里面的关键字】

1
./afrog -t url -s CVE-2021-26855 -o result.html

6.按照POC等级扫描

info, low, medium, high, critical

1
./afrog -t URL -S high,critical

7.使用自定义yaml文件POC扫描漏洞

1
./afrog -t URL -P xxx.yaml		(--debug/-debug请求的详细情况)

8.在线更新【afrog-pocs】

1
./afrog --up

9.禁止指纹识别,直接漏扫

1
./afrog -t url -nf

自定义yaml编写

使用特定的yaml文件 afrog -t URL -P yaml文件/路径

1
2
3
4
5
6
7
afrog.exe -P afrog_test.yaml -t URL -o result.txt

测试输出,调试
afrog.exe -P afrog_test.yaml -t URL --debug


afrog不允许跳出,https访问,不允许跳出 【不安全证书,不能跳过】

必须字段(缺少会导致解析失败)

字段 说明 示例
id 漏洞的唯一标识(建议用 CVE-XXXX 或自定义格式)。 id: CVE-2024-1234
info.name 漏洞名称(简短描述)。 name: “Apache Solr RCE”
info.serverity 漏洞严重性(info/low/medium/high/critical)。 severity: high
rules 定义检测规则(至少一个规则,如 r0)。 见上方示例
expression 最终判断漏洞的逻辑(必须引用规则结果,如 r0())。 expression: r0()

规则部分(rules)必须字段

字段 说明 示例
request 定义 HTTP 请求(方法、路径等)。 method: GET
path: "/admin"
expression 当前规则的匹配逻辑(如状态码、响应内容)。 response.status == 200
response.body.bcontains(b"do_cmd.asp")

可选字段

字段 用途 示例
info.description 漏洞详细描述。 description: "A RCE in..."
info.tags 分类标签(便于筛选)。 tags: rce,solr
info.author 作者信息。 author: "yourname"
info.reference 参考链接(CVE/公告)。 reference: "https://nvd.nist.gov..."
headers 自定义请求头。 User-Agent: Mozilla/5.0
output 提取响应中的数据(如 Token)。 output: ["{{match.1}}"]

在afrog的yaml中,rules下的r0,r1等是规则组(Rule Groups)的标识,用于定义多个独立的规则检测规则,并按顺序执行。这种设计运行你在一个poc中编写多步骤的漏洞检测逻辑

示例1–get请求

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
id: sql-labs

info:
name: sql-labs-get
serverity: critical
author: first
description: |
This is a test POC for detecting a sample vulnerability.

rules:
r0:
request:
method: GET
redirect: false //避免重定向302
path: "/sqli-labs/Less-1/?id=1'"
headers:
User-Agent: afrog-scanner
expression: response.status == 200 && response.body.bcontains(b"You have an error in your SQL syntax")
expression: r0()

示例2–post请求(表单提交)

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
id: sql-labs

info:
name: sql-labs-get
severity: critical
author: first
description: |
This is a test POC for detecting a sample vulnerability.

rules:
r0:
request:
method: POST
path: /sqli-labs/Less-11/
headers:
Accept-Encoding: gzip, deflate
Content-Type: application/x-www-form-urlencoded
Content-Length: 31
body: "uname=test%27+--%2B&passwd=test&submit=Submit"
expression: response.status == 200 && response.body.bcontains(b"You have an error in your SQL syntax")
expression: r0()

示例3–post请求(json提交)

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
id: ruoyi-json

info:
name: ruoyi-json
severity: critical
author: first
description: |
This is a test POC for detecting a sample vulnerability.

rules:
r0:
request:
method: POST
path: /prod-api/login
headers:
Accept-Encoding: gzip, deflate
Content-Type: application/json
body: |
{
"username":"admin",
"password":"admin123",
"code":"6",
"uuid":"1c5e6a67addc4e5a8248f940932a0456"
}
expression: response.status == 200
expression: r0()

结论,post请求,数据传输均用body定义,根据不同的content-Type来设定不同的内容。

示例4–联合请求

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
id: sql-labs

info:
name: sql-labs-get
serverity: critical
author: first
description: |
This is a test POC for detecting a sample vulnerability.

rules:
r0:
request:
method: GET
redirect: false
path: "/sqli-labs/Less-1/?id=1'"
headers:
User-Agent: afrog-scanner
expression: response.status == 200 && response.body.bcontains(b"You have an error in your SQL syntax")
r1:
request:
method: POST
path: /sqli-labs/Less-11/
headers:
Accept-Encoding: gzip, deflate
Content-Type: application/x-www-form-urlencoded
Content-Length: 31
body: "uname=test%27+--%2B&passwd=test&submit=Submit"
expression: response.status == 200 && response.body.bcontains(b"You have an error in your SQL syntax")
expression: r0() && r1()

nuclei

基本使用

1.扫描单个url

1
./nuclei -u url -o result.txt  [-me reult md文档]

2.扫描多个url

1
./nuclei -l targets.txt

3.使用特定的模板或目录

1
2
./nuclei -u url -t demo.yaml   [单个特定的目录]
./nuclei -u url -t demo1.yaml -t demo2.yaml [多个特定的目录或文件]

4.指定特定的标签的模板

1
./nuclei -u url -tags jira,generic

5.根据严重程度指定模板

1
./nuclei -u url -s critical,high,medium

6.限定速度

1
2
3
4
./nuclei -l targets.txt -rl 50 -c 10

-rl -rate-limit int 每秒最大请求量(默认150
-c -concurrency int 并行执行的最大模板数量(默认25

7.指定自定义的yaml文件

1
./nuclei -t demo.yaml -u url  (--debug/-debug请求的详细情况)

8.更新nuclei到最新版本

1
./nuclei -up

9.更新nuclei模板到最新版本

1
./nuclei -ut

10.查看所有poc

1
./nuclei -tl

image-20250502204348843

自定义yaml编写

指定自定义yaml文件

1
nuclei.exe -t nuclei_test.yaml -u http://192.168.18.129/

关键组件说明

  1. id: 模板的唯一标识符

  2. info: 包含模板的元数据

    • name: 漏洞名称
    • author: 作者
    • severity: 严重程度 (low, medium, high, critical)
    • description: 详细描述
    • reference: 参考链接
    • tags: 相关标签
  3. requests: 定义HTTP请求

    • method: HTTP方法 (GET, POST等)
    • path: 请求路径
    • matchers: 定义如何识别漏洞
    • extractors: 从响应中提取数据
  4. matchers: 匹配响应内容的规则

    • type: 匹配类型 (word, regex等)
    • words/regex: 要匹配的内容
    • part: 匹配响应哪部分 (body, header等)
    • condition: 匹配条件 (and, or)

matchers支持的匹配方法

可以匹配:word,regex,dsl,status

1
2
3
4
5
matchers:
- type: <匹配类型> # 如 word, regex, dsl, status
<匹配参数>: <值> # 如 words, regex, dsl, status 等
condition: and/or # 多个条件时的逻辑关系(默认 and)
part: body/header/all # 匹配响应体、头部或全部(默认 body)

word匹配

1
2
3
4
5
6
7
matchers:
- type: word
words: # 可指定多个关键字
- "admin"
- "password"
condition: or # 满足任意一个即可
part: body # 默认检查 body,可选 header/all

regex匹配

1
2
3
4
5
matchers:
- type: regex
regex:
- '[0-9]{4}-[0-9]{4}-[0-9]{4}' # 匹配类似信用卡号
condition: and

dsl动态脚本匹配

1
2
3
4
5
6
7
matchers:
- type: dsl
dsl:
- 'contains(body, "Login Page")' # 检查 body 是否包含 "Login Page"
- 'status_code == 200' # 状态码是否为 200
- 'len(body) < 1000' # 响应体长度是否小于 1000
condition: and # 所有条件必须满足

status匹配

1
2
3
4
5
matchers:
- type: status
status:
- 200
- 302

示例1–get请求

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
id: sql-labs

info:
name: sql-labs
author: first
severity: high
description: |
This is a test POC for detecting a sample vulnerability.

requests:
- method: GET
path:
- "{{BaseURL}}/sqli-labs/Less-1/?id=1'"
matchers-condition: and
matchers:
- type: status
status:
- 200
- type: word
words:
- "You have an error in your SQL syntax"

示例–post(表单)

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
id: sql-labs

info:
name: sql-labs
author: first
severity: high
description: |
This is a test POC for detecting a sample vulnerability.

http:
- method: POST
path:
- "{{BaseURL}}/sqli-labs/Less-11/"
body: "uname=test%27+--%2B&passwd=test&submit=Submit"
headers:
Accept-Encoding: "gzip, deflate"
Content-Type: "application/x-www-form-urlencoded"
matchers-condition: and
matchers:
- type: status
status:
- 200
- type: word
words:
- "You have an error in your SQL syntax"

示例3–post(json)

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
id: sql-labs

info:
name: sql-labs
author: first
severity: high
description: |
This is a test POC for detecting a sample vulnerability.

http:
- method: POST
path:
- "{{BaseURL}}/prod-api/login"
body: |
{
"username":"admin",
"password":"admin123",
"code":"6",
"uuid":"1c5e6a67addc4e5a8248f940932a0456"
}
headers:
Accept-Encoding: "gzip, deflate"
Content-Type: application/json
matchers-condition: and
matchers:
- type: status
status:
- 200

示例4–联合

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
id: sql-labs
info:
name: sql-labs
author: first
severity: high
tags: H3C,RCE

flow: http(1) && http(2)

http:
- method: POST
path:
- "{{BaseURL}}/sqli-labs/Less-11/"
headers:
Accept-Encoding: "gzip, deflate"
Content-Type: "application/x-www-form-urlencoded"
body: "uname=test%27+--%2B&passwd=test&submit=Submit"
matchers-condition: and
matchers:
- type: status
status:
- 200
- type: word
words:
- "You have an error in your SQL syntax"

- method: GET
path:
- "{{BaseURL}}/sqli-labs/Less-1/?id=1'"
matchers:
- type: status
status:
- 200