### Install fscanx Library
Source: https://github.com/killmonday/fscanx/blob/master/mylib/finger/README.md
Use 'go get' to install the fscanx library and its dependencies.
```bash
go get github.com/chainreactors/fingers@master
```
--------------------------------
### Fingers Tool Output Example (Normal Mode)
Source: https://github.com/killmonday/fscanx/blob/master/mylib/finger/cmd/engine/README.md
Example output in normal mode, typically showing detected web server and operating system information.
```text
nginx/1.18.0 ubuntu/20.04
```
--------------------------------
### Optimized Remote Proxy Scan Configuration Example
Source: https://context7.com/killmonday/fscanx/llms.txt
An example demonstrating an optimized configuration for remote proxy scanning using fscanx, combining proxy settings with scan parameters for efficiency.
```bash
fscanx -socks5 socks5://127.0.0.1:1080 \
-h 192.168.1.1/24 \
-nmap -np \
-t 50 -tn 30 \
-time 8 -wt 12 \
-o internal_scan.txt
```
--------------------------------
### Install goftp Package
Source: https://github.com/killmonday/fscanx/blob/master/mylib/ftp/README.md
Use this command to install or update the goftp package to your Go project.
```bash
go get -u github.com/jlaffaye/ftp
```
--------------------------------
### Full HTTP Fingerprint Configuration Example
Source: https://github.com/killmonday/fscanx/blob/master/mylib/finger/doc/rule.md
A comprehensive example of an HTTP fingerprint configuration, illustrating all available fields and their potential uses. This serves as a reference for complex fingerprint definitions.
```yaml
- name: frame
default_port:
- '1111'
protocol: http
rule:
- version: v1.1.1
regexps:
vuln:
- version:(.*)
regexp:
- "finger.*test"
header:
- string
body:
- string
md5:
- [md5]
mmh3:
- [mmh3]
version:
- version:(.*)
favicon:
md5:
- f7e3d97f404e71d302b3239eef48d5f2
mmh3:
- '516963061'
level: 1
send_data: "info\n"
vuln: frame_unauthorized
```
--------------------------------
### Port Configuration Example (RDP)
Source: https://github.com/killmonday/fscanx/blob/master/mylib/finger/doc/rule.md
An excerpt from a 'port.yaml' file showing how default ports for services can be defined. This example lists common ports associated with the RDP service.
```yaml
- name: rdp
ports:
- '3389'
- '13389'
- '33899'
- "33389"
```
--------------------------------
### Fingers Tool Output Example (Verbose Mode)
Source: https://github.com/killmonday/fscanx/blob/master/mylib/finger/cmd/engine/README.md
Example output when the verbose flag (-v) is used, providing details about loaded engines and detected frameworks, including name, vendor, product, version, and CPE information.
```text
Loaded engines: fingers:1000 fingerprinthub:500 wappalyzer:300
Detected frameworks for https://example.com:
Name: nginx
Vendor: nginx
Product: nginx
Version: 1.18.0
CPE: cpe:/a:nginx:nginx:1.18.0
---
Name: ubuntu
Vendor: canonical
Product: ubuntu
Version: 20.04
CPE: cpe:/o:canonical:ubuntu:20.04
---
```
--------------------------------
### Connect and Login to FTP Server
Source: https://github.com/killmonday/fscanx/blob/master/mylib/ftp/README.md
Example demonstrating how to establish a connection to an FTP server with a timeout and log in using anonymous credentials. Ensure proper error handling for connection and login failures.
```go
c, err := ftp.Dial("ftp.example.org:21", ftp.DialWithTimeout(5*time.Second))
if err != nil {
log.Fatal(err)
}
err = c.Login("anonymous", "anonymous")
if err != nil {
log.Fatal(err)
}
// Do something with the FTP conn
if err := c.Quit(); err != nil {
log.Fatal(err)
}
```
--------------------------------
### Fscanx Command-Line Usage Examples
Source: https://github.com/killmonday/fscanx/blob/master/README.md
Demonstrates various command-line arguments for fscanx, including network range scanning, asset information gathering, web scanning, and proxy configurations.
```bash
fscanx -h 192.168.0.0/16 -auto -nmap -t 1000 -np
```
```bash
fscanx -hf target.txt -pd -nmap -np
```
```bash
fscanx -hf url.txt -tn 200
```
```bash
fscanx -socks5 socks5://127.0.0.1:1080 -h 192.168.1.1/16 -auto
```
```bash
fscanx -socks5 socks5://127.0.0.1:1080 -h 192.168.1.1/24 -poc -p 80,443,8080
```
```bash
fscanx -socks5 socks5://127.0.0.1:1080 -h 192.168.1.1/24 -br -p 21,22,445,3306,6379
```
```bash
fscanx -socks5 socks5://127.0.0.1:1080 -h 192.168.1.1/24 -br -p 445 -user administrator,admin -pwd 123456,admin
```
--------------------------------
### Full fscanx Usage Example with Custom Engine in Go
Source: https://github.com/killmonday/fscanx/blob/master/mylib/finger/doc/sdk.md
Demonstrates how to integrate a custom engine into the fscanx framework. This includes creating a main engine, registering the custom engine, performing detection using specific or all engines, and managing engine states (enable/disable).
```go
package main
import (
"fmt"
"net/http"
"github.com/chainreactors/fingers"
"path/to/your/customengine"
)
func main() {
// 创建包含自定义引擎的引擎列表
engine, err := fingers.NewEngine(fingers.FingersEngine, fingers.WappalyzerEngine)
if err != nil {
panic(err)
}
// 注册自定义引擎
customEngine, err := customengine.NewCustomEngine()
if err != nil {
panic(err)
}
if !engine.Register(customEngine) {
fmt.Println("Failed to register custom engine")
return
}
// 验证引擎状态
fmt.Printf("已注册引擎: %s\n", engine.String())
// 使用特定引擎进行匹配
resp, err := http.Get("http://example.com")
if err != nil {
return
}
// 只使用自定义引擎
customFrameworks := engine.MatchWithEngines(resp, "custom")
fmt.Printf("自定义引擎结果: %s\n", customFrameworks.String())
// 使用所有引擎
allFrameworks, _ := engine.DetectResponse(resp)
fmt.Printf("所有引擎结果: %s\n", allFrameworks.String())
// 禁用/启用引擎
engine.Disable("custom")
engine.Enable("custom")
}
```
--------------------------------
### Read a File from FTP Server
Source: https://github.com/killmonday/fscanx/blob/master/mylib/ftp/README.md
Example for downloading a file from the FTP server. It retrieves the file content into a reader, reads all data into a buffer, and prints it as a string. Remember to close the reader after use.
```go
r, err := c.Retr("test-file.txt")
if err != nil {
panic(err)
}
defer r.Close()
buf, err := ioutil.ReadAll(r)
println(string(buf))
```
--------------------------------
### Progress Information Example
Source: https://github.com/killmonday/fscanx/blob/master/mylib/finger/cmd/nmap/README.md
Shows the format of real-time progress information during a scan, including percentage complete, speed, and counts of open or identified ports.
```text
📈 进度: 45.2% (1810/4000) | 速度: 156.3/s | 开放: 23 | 识别: 15
```
--------------------------------
### Alias Block Configuration Example
Source: https://github.com/killmonday/fscanx/blob/master/mylib/finger/doc/sdk.md
This configuration example shows how to use the 'block' field within an alias definition to prevent specific engines from contributing to the final result, helping to resolve false positives. In this case, the 'goby' engine is blocked if it identifies 'UFIDA NC'.
```yaml
- name: 用友 NC
vendor: yonyou
product: NC
block:
- goby # 需要屏蔽的engine
alias:
fingers:
- 用友NC
ehole:
- 用友NC
- YONYOU NC
goby:
- UFIDA NC
fingerprinthub:
- yonyou-ufida-nc
```
--------------------------------
### Scan Results Example
Source: https://github.com/killmonday/fscanx/blob/master/mylib/finger/cmd/nmap/README.md
Illustrates the format of scan results, showing identified services, versions, and port states for different hosts and ports.
```text
✅ 192.168.1.1:80 -> nginx [nginx] v1.18.0 [http, web-server]
✅ 192.168.1.1:443 -> nginx [nginx] v1.18.0 [https, web-server, tls]
🔍 192.168.1.1:22 -> 已识别但无详细信息
🔓 192.168.1.1:3389 -> 端口开放
```
--------------------------------
### Detect Frameworks from HTTP Response
Source: https://github.com/killmonday/fscanx/blob/master/mylib/finger/doc/sdk.md
This Go code snippet demonstrates how to initialize an fscanx engine, make an HTTP GET request, and detect web frameworks from the response. It shows how to access the number of detected frameworks, format the output, retrieve specific frameworks, and iterate through the detected frameworks.
```go
package main
import (
"fmt"
"net/http"
"github.com/chainreactors/fingers"
)
func main() {
engine, err := fingers.NewEngine()
if err != nil {
panic(err)
}
resp, err := http.Get("https://example.com")
if err != nil {
return
}
frameworks, err := engine.DetectResponse(resp)
if err != nil {
return
}
// 获取数量和格式化输出
fmt.Printf("检测到 %d 个框架: %s\n", frameworks.Len(), frameworks.String())
// 获取特定框架
if nginx, exists := frameworks.Get("nginx"); exists {
fmt.Printf("找到 Nginx: %s\n", nginx.String())
}
// 转换为切片进行迭代
for _, framework := range frameworks.ToSlice() {
fmt.Printf("- %s (来源: %s)\n", framework.Name, framework.From)
if framework.CPE() != "" {
fmt.Printf(" CPE: %s\n", framework.CPE())
}
}
// 过滤操作
webServers := frameworks.Filter(func(f *common.Framework) bool {
for _, tag := range f.Tags {
if tag == "web-server" {
return true
}
}
return false
})
// 合并其他结果
frameworks.Merge(otherFrameworks)
}
```
--------------------------------
### TCP Fingerprint Configuration Example (RDP)
Source: https://github.com/killmonday/fscanx/blob/master/mylib/finger/doc/rule.md
An example of a TCP fingerprint configuration. It specifies the protocol as 'tcp', provides a regular expression for matching initial packet data, and uses 'send_data' for active probing. Binary data in 'send_data' should be encoded (e.g., base64).
```yaml
- name: rdp
default_port:
- rdp
protocol: tcp
rule:
- regexps:
regexp:
- "^\x03\0\0"
send_data: b64de|AwAAKiXgAAAAAABDb29raWU6IG1zdHNoYXNoPW5tYXANCgEACAADAAAA
```
--------------------------------
### Nginx Alias Configuration Example
Source: https://github.com/killmonday/fscanx/blob/master/mylib/finger/doc/sdk.md
This YAML configuration demonstrates how to define an alias for Nginx, specifying its vendor, product, labels, priority, target URLs, and alias mappings for different fingerprint libraries.
```yaml
- name: nginx
vendor: nginx
product: nginx
label: web,server,proxy
priority: 2
target:
- https://nginx.org
- nginx.org:80
alias:
fingers:
- nginx
ehole:
- nginx
goby:
- nginx
wappalyzer:
- Nginx
fingerprinthub:
- nginx
block: []
```
--------------------------------
### Discover Internal Web Services
Source: https://github.com/killmonday/fscanx/blob/master/mylib/finger/cmd/nmap/README.md
Example for discovering internal web services across a large private network range (192.168.0.0/16) with high concurrency (300 threads).
```bash
./nmap-scanner -cidr 192.168.0.0/16 -port 80,443,8080,8443 -threads 300
```
--------------------------------
### Discover Internal Common Services
Source: https://github.com/killmonday/fscanx/blob/master/mylib/finger/cmd/nmap/README.md
Example for discovering common internal services across a large private network range (10.0.0.0/8) with 200 threads.
```bash
./nmap-scanner -cidr 10.0.0.0/8 -port 22,80,443,3389,1433,3306 -threads 200
```
--------------------------------
### Test Single Fingerprint with YAML Configuration
Source: https://github.com/killmonday/fscanx/blob/master/mylib/finger/fingers/README.md
This Go code demonstrates testing a single fingerprint rule defined in YAML format. It uses `yaml.v3` for unmarshalling and `Finger.Match` for matching against test content. The example includes both keyword and regex matching, with the regex capturing the version number. Ensure the YAML is correctly structured.
```go
package main
import (
"fmt"
"gopkg.in/yaml.v3"
"github.com/chainreactors/fingers/fingers"
)
func main() {
// YAML 格式的指纹配置
fingerYAML := `
name: apache
rule:
- method: keyword
keyword: ["Apache"]
- method: regex
regex: "Apache/([\d\.]+)"
version: "\1"
`
// 反序列化创建指纹
var finger fingers.Finger
err := yaml.Unmarshal([]byte(fingerYAML), &finger)
if err != nil {
panic(err)
}
// 编译指纹规则
err = finger.Compile(false)
if err != nil {
panic(err)
}
// 测试内容
testContent := []byte(`HTTP/1.1 200 OK
Server: Apache/2.4.41
Content-Type: text/html
Apache Server`)
content := fingers.NewContent(testContent, "", true)
// 执行匹配
framework, vuln, matched := finger.Match(content, 0, nil)
if matched {
fmt.Printf("✓ 匹配成功: %s\n", framework.String())
if framework.Version != "" {
fmt.Printf(" 版本: %s\n", framework.Version)
}
}
}
```
--------------------------------
### Scan Single IP with Common Ports
Source: https://github.com/killmonday/fscanx/blob/master/mylib/finger/cmd/nmap/README.md
Basic usage example to scan common ports (22, 80, 443) on a single IP address.
```bash
./nmap-scanner -cidr 192.168.1.1 -port 22,80,443
```
--------------------------------
### Scan Entire C-Class Network for HTTP Services
Source: https://github.com/killmonday/fscanx/blob/master/mylib/finger/cmd/nmap/README.md
Example demonstrating how to scan an entire C-class subnet (192.168.1.0/24) specifically for HTTP services on ports 80, 443, and 8080.
```bash
./nmap-scanner -cidr 192.168.1.0/24 -port 80,443,8080
```
--------------------------------
### HTTP Fingerprint Configuration for Extracting Version from Body
Source: https://github.com/killmonday/fscanx/blob/master/mylib/finger/doc/rule.md
An example of an HTTP fingerprint configuration that extracts version information directly from the HTML body using regular expressions. Multiple regex patterns can be provided.
```yaml
- name: tomcat
rule:
- regexps:
regexp:
- Apache Tomcat/(.*)
- Apache Tomcat/(.*)
```
--------------------------------
### Final Statistics Example
Source: https://github.com/killmonday/fscanx/blob/master/mylib/finger/cmd/nmap/README.md
Displays the final statistics after a scan is completed, summarizing total time, targets scanned, open ports, identified services, and overall scan speed.
```text
✅ 扫描完成!
总耗时: 25.6s
扫描目标: 4000
开放端口: 23
识别服务: 15
扫描速度: 156.25 targets/sec
```
--------------------------------
### Create FingersEngine Instance
Source: https://github.com/killmonday/fscanx/blob/master/mylib/finger/fingers/README.md
Initializes the FingersEngine with default configurations. Ensure error handling for successful initialization.
```go
package main
import (
"fmt"
"github.com/chainreactors/fingers/fingers"
)
func main() {
// 使用默认配置创建引擎
engine, err := fingers.NewFingersEngine()
if err != nil {
panic(err)
}
fmt.Printf("FingersEngine 加载完成,包含 %d 个指纹\n", engine.Len())
}
```
--------------------------------
### Create FingersEngine with Custom Fingerprint Libraries
Source: https://github.com/killmonday/fscanx/blob/master/mylib/finger/fingers/README.md
Initializes the FingersEngine using custom HTTP and/or Socket fingerprint libraries loaded from JSON files. This allows for tailored detection capabilities.
```go
package main
import (
"fmt"
"os"
"github.com/chainreactors/fingers/fingers"
)
func main() {
// 加载自定义 HTTP 指纹库
httpConfig, err := os.ReadFile("custom_http_fingers.json")
if err != nil {
panic(err)
}
// 加载自定义 Socket 指纹库(可选)
socketConfig, err := os.ReadFile("custom_socket_fingers.json")
if err != nil {
// Socket 配置是可选的
socketConfig = nil
}
// 使用自定义配置创建引擎
engine, err := fingers.NewFingersEngineWithCustom(httpConfig, socketConfig)
if err != nil {
panic(err)
}
fmt.Printf("使用自定义指纹库创建引擎成功,包含 %d 个指纹\n", engine.Len())
// 正常使用引擎进行检测
// ...
}
```
--------------------------------
### Active HTTP Fingerprint Identification Example (Nacos)
Source: https://github.com/killmonday/fscanx/blob/master/mylib/finger/doc/rule.md
An example of active fingerprint identification where a specific path is sent in 'send_data' to elicit a response. The fingerprint matches if a specific string (e.g., favicon path) is found in the response body. The 'focus' field marks important fingerprints.
```yaml
- name: nacos
focus: true
rule:
- regexps:
body:
- console-ui/public/img/favicon.ico
send_data: /nacos
```
--------------------------------
### High Concurrency Scan
Source: https://github.com/killmonday/fscanx/blob/master/mylib/finger/cmd/nmap/README.md
Example of performing a high concurrency scan with 200 threads on a subnet, targeting common ports.
```bash
./nmap-scanner -cidr 192.168.1.0/24 -port 22,80,443,3389 -threads 200
```
--------------------------------
### 测试阶段:测试别名和指纹
Source: https://github.com/killmonday/fscanx/blob/master/mylib/finger/cmd/README.md
在测试阶段,使用 test 工具测试别名配置和新指纹的准确性。需要在 cmd/test 目录下运行。
```bash
cd cmd/test
go run main.go -alias test_aliases.yaml -name new_fingerprint_test
```
--------------------------------
### 通用指纹检测
Source: https://github.com/killmonday/fscanx/blob/master/mylib/finger/cmd/README.md
使用 test 工具对指定目标进行通用指纹检测。需要在 cmd/test 目录下运行。
```bash
cd cmd/test
go run main.go -target https://nginx.org -detect-all
```
--------------------------------
### Fast Scan of Common Ports
Source: https://github.com/killmonday/fscanx/blob/master/mylib/finger/cmd/nmap/README.md
Example of a fast scan with high concurrency (500 threads) and a short timeout (2 seconds) for common ports on a subnet.
```bash
./nmap-scanner -cidr 192.168.1.0/24 -port 22,80,443,3389 -threads 500 -timeout 2
```
--------------------------------
### Register Custom Engine with fscanx
Source: https://github.com/killmonday/fscanx/blob/master/mylib/finger/doc/sdk.md
This Go code demonstrates how to register a custom fingerprint engine with the main fscanx engine. It shows the process of creating a standard engine, initializing a custom engine with its fingerprints, registering the custom engine, and then using the combined engine to detect frameworks from an HTTP response.
```go
func main() {
// 创建标准引擎
engine, err := fingers.NewEngine()
if err != nil {
panic(err)
}
// 创建自定义引擎
customEngine := &CustomEngine{
name: "custom",
fingerprints: loadCustomFingerprints(),
}
// 注册到引擎中
success := engine.Register(customEngine)
if !success {
log.Println("Failed to register custom engine")
return
}
// 使用引擎进行指纹识别
resp, err := http.Get("http://example.com")
if err != nil {
return
}
frameworks, err := engine.DetectResponse(resp)
if err != nil {
return
}
fmt.Println("检测到的指纹:")
for _, framework := range frameworks {
fmt.Printf("- %s\n", framework.String())
if framework.CPE() != "" {
fmt.Printf(" CPE: %s\n", framework.CPE())
}
}
}
```
--------------------------------
### Testing a Single Fingers Engine
Source: https://github.com/killmonday/fscanx/blob/master/mylib/finger/doc/sdk.md
This test function initializes a FingersEngine, fetches content from a URL, and then uses WebMatch to identify frameworks based on the response content. It iterates through the matched frames and logs them.
```go
func TestFingersEngine(t *testing.T) {
engine, err := fingers.NewFingersEngine()
if err != nil {
t.Error(err)
}
resp, err := http.Get("http://127.0.0.1")
if err != nil {
return
}
content := httputils.ReadRaw(resp)
frames := engine.WebMatch(content)
for _, frame := range frames {
t.Log(frame)
}
}
```
--------------------------------
### Test All Aliases
Source: https://github.com/killmonday/fscanx/blob/master/mylib/finger/doc/sdk.md
This command-line instruction shows how to run tests for all defined aliases in the specified alias file.
```bash
# 对所有alias进行测试
go run main.go -alias aliases.yaml
```
--------------------------------
### 运行 nmap 工具
Source: https://github.com/killmonday/fscanx/blob/master/mylib/finger/cmd/README.md
使用 nmap 工具进行目标和端口的服务指纹识别。需要在 cmd/nmap 目录下运行。
```bash
cd cmd/nmap
go run nmap.go [target] [port]
```
--------------------------------
### Initialize Custom Engine in Go
Source: https://github.com/killmonday/fscanx/blob/master/mylib/finger/doc/sdk.md
Provides a function to create and initialize a custom engine, loading fingerprint data and pre-compiling regular expressions. Ensure your fingerprint data source (e.g., custom_fingerprints.json) is correctly configured.
```go
func NewCustomEngine() (*CustomEngine, error) {
engine := &CustomEngine{
name: "custom",
}
// 加载指纹数据
err := engine.loadFingerprints()
if err != nil {
return nil, err
}
return engine, nil
}
func (e *CustomEngine) loadFingerprints() error {
// 从文件、数据库或其他数据源加载指纹
// 例如:从JSON文件加载
data, err := ioutil.ReadFile("custom_fingerprints.json")
if err != nil {
return err
}
var fingerprints []CustomFingerprint
err = json.Unmarshal(data, &fingerprints)
if err != nil {
return err
}
// 预编译正则表达式
for i := range fingerprints {
for j := range fingerprints[i].Rules {
regex, err := regexp.Compile(fingerprints[i].Rules[j].Pattern)
if err != nil {
return fmt.Errorf("failed to compile regex %s: %v",
fingerprints[i].Rules[j].Pattern, err)
}
fingerprints[i].Rules[j].Regex = regex
}
}
e.fingerprints = fingerprints
return nil
}
```
--------------------------------
### 开发阶段:验证新指纹文件
Source: https://github.com/killmonday/fscanx/blob/master/mylib/finger/cmd/README.md
在开发阶段,使用 validate 工具验证新创建的指纹文件的格式。需要在 cmd/validate 目录下运行。
```bash
cd cmd/validate
go run main.go -engine fingers new_fingerprints.yaml
```
--------------------------------
### Detect Content Fingerprints
Source: https://github.com/killmonday/fscanx/blob/master/mylib/finger/README.md
Initialize the engine and detect fingerprints from HTTP response content. Ensure the target URL is accessible.
```Go
func TestEngine(t *testing.T) {
engine, err := NewEngine()
if err != nil {
panic(err)
}
resp, err := http.Get("http://127.0.0.1:8080/")
if err != nil {
return
}
content := httputils.ReadRaw(resp)
frames, err := engine.DetectContent(content)
if err != nil {
return
}
fmt.Println(frames.String())
}
```
--------------------------------
### Load and Validate Fingerprints from Byte Slice
Source: https://github.com/killmonday/fscanx/blob/master/mylib/finger/fingers/README.md
Demonstrates how to load and automatically validate a list of fingerprints directly from a byte slice using `fingers.LoadFingers`. It then compiles each loaded fingerprint to verify its syntax.
```go
package main
import (
"fmt"
"github.com/chainreactors/fingers/fingers"
)
func main() {
// 直接使用 LoadFingers 加载和验证
content := []byte(`[
{
"name": "nginx",
"rule": [
{
"regexps": {
"header": ["Server: nginx"]
},
"level": 0
}
]
}
]`)
// LoadFingers 会自动验证格式
fingerprintList, err := fingers.LoadFingers(content)
if err != nil {
fmt.Printf("加载失败: %v\n", err)
return
}
// 编译验证每个指纹
for _, finger := range fingerprintList {
if err := finger.Compile(false); err != nil {
fmt.Printf("指纹 '%s' 编译失败: %v\n", finger.Name, err)
} else {
fmt.Printf("指纹 '%s' 验证通过\n", finger.Name)
}
}
}
```
--------------------------------
### 运行 transform 工具
Source: https://github.com/killmonday/fscanx/blob/master/mylib/finger/cmd/README.md
执行 transform 工具进行数据转换操作。需要在 cmd/transform 目录下运行。
```bash
cd cmd/transform
go run transform.go [options]
```
--------------------------------
### Compile and Run Nmap Scanner
Source: https://github.com/killmonday/fscanx/blob/master/mylib/finger/cmd/nmap/README.md
Instructions for compiling the nmap scanner tool or running it directly using go run. Navigate to the project directory before executing these commands.
```bash
cd cmd/nmap
go build -o nmap-scanner .
# or run directly
go run .
```
--------------------------------
### Testing the Nmap Engine for Service Matching
Source: https://github.com/killmonday/fscanx/blob/master/mylib/finger/doc/sdk.md
This test function initializes an NmapEngine and uses ServiceMatch to identify services running on a specific host and port. It prints details about the matched framework, including whether it's a guess and its CPE.
```go
func TestNmapEngine(t *testing.T) {
engine, err := gonmap.NewNmapEngine()
if err != nil {
t.Error(err)
}
sender := common.NewServiceSender(5 * time.Second)
result := engine.ServiceMatch("127.0.0.1", 22, 3, sender, nil)
if result != nil && result.Framework != nil {
fmt.Printf("Service: %s\n", result.Framework.String())
if result.Framework.IsGuess() {
fmt.Println("This is a guess based on port number")
}
if result.Framework.CPE() != "" {
fmt.Printf("CPE: %s\n", result.Framework.CPE())
}
}
}
```
--------------------------------
### Store a File on FTP Server
Source: https://github.com/killmonday/fscanx/blob/master/mylib/ftp/README.md
This snippet shows how to upload a file to the FTP server. It creates a buffer with string data and uses the Stor command. Handle potential errors during the upload process.
```go
data := bytes.NewBufferString("Hello World")
err = c.Stor("test-file.txt", data)
if err != nil {
panic(err)
}
```
--------------------------------
### Enable RDP Probing with -screen
Source: https://github.com/killmonday/fscanx/blob/master/README.md
Activate RDP probing with the -screen flag to detect Windows system versions and hostnames, and capture RDP screenshots.
```bash
fscanx -screen
```
--------------------------------
### HTTP Fingerprint Configuration Using Version Field
Source: https://github.com/killmonday/fscanx/blob/master/mylib/finger/doc/rule.md
This configuration demonstrates how to map a specific version to a fingerprint by matching a body string and explicitly defining the version using the 'version' field. This is useful when version keywords are not directly in the version string.
```yaml
- name: tomcat
rule:
- version: v8
regexps:
body:
- Apache Tomcat/8
```
--------------------------------
### Registering a Custom Engine
Source: https://github.com/killmonday/fscanx/blob/master/mylib/finger/doc/sdk.md
This function demonstrates how to register a custom engine that implements the EngineImpl interface with the Fscanx Engine. Ensure the custom engine is created successfully before registration.
```go
func RegisterCustomEngine(engine *fingers.Engine) error {
customEngine, err := NewCustomEngine()
if err != nil {
return err
}
engine.Register(customEngine)
return nil
}
```
--------------------------------
### Enable Fingerprint Recognition with -nmap
Source: https://github.com/killmonday/fscanx/blob/master/README.md
Use the -nmap flag to enable service protocol and web product fingerprint recognition. Unrecognized ports will be marked as 'open'.
```bash
fscanx -nmap
```
--------------------------------
### 运行 engine 示例
Source: https://github.com/killmonday/fscanx/blob/master/mylib/finger/cmd/README.md
执行 engine 工具下的示例代码,展示如何使用 Fingers 引擎。需要在 cmd/engine 目录下运行。
```bash
cd cmd/engine
go run example.go
```
--------------------------------
### Adding New Fingerprints (Web)
Source: https://github.com/killmonday/fscanx/blob/master/README.md
Instructions for adding new web fingerprints by editing and re-compressing JSON files. Requires `gzip` for compression.
```bash
gzip -c fingers_http.json > fingers_http.json.gz
```
--------------------------------
### Implement Custom Fingerprint Engine
Source: https://github.com/killmonday/fscanx/blob/master/mylib/finger/doc/sdk.md
This Go code defines a custom fingerprint engine by implementing the `EngineImpl` interface. It includes structures for the custom engine and fingerprint definitions, along with methods for naming, compiling, checking capability, and matching web fingerprints. The `WebMatch` function iterates through custom fingerprints and applies matching logic to the provided content.
```go
package customengine
import (
"github.com/chainreactors/fingers/common"
)
type CustomEngine struct {
name string
// 指纹库数据
fingerprints []CustomFingerprint
}
// 实现 EngineImpl 接口
func (e *CustomEngine) Name() string {
return e.name
}
func (e *CustomEngine) Compile() error {
// 编译指纹数据,如加载资源文件、预处理正则表达式等
return nil
}
func (e *CustomEngine) Len() int {
return len(e.fingerprints)
}
// 声明引擎能力
func (e *CustomEngine) Capability() common.EngineCapability {
return common.EngineCapability{
SupportWeb: true, // 支持Web指纹
SupportService: false, // 不支持Service指纹
}
}
// Web指纹匹配实现
func (e *CustomEngine) WebMatch(content []byte) common.Frameworks {
frameworks := make(common.Frameworks)
// 自定义匹配逻辑
for _, fp := range e.fingerprints {
if fp.Match(content) {
framework := common.NewFramework(fp.Name, common.FrameFromDefault)
// 设置CPE信息
if fp.Vendor != "" || fp.Product != "" {
framework.UpdateAttributes(&common.Attributes{
Part: "a",
Vendor: fp.Vendor,
Product: fp.Product,
Version: fp.Version,
})
}
frameworks[fp.Name] = framework
}
}
return frameworks
}
// Service指纹匹配实现(如果不支持Service指纹可以返回nil)
func (e *CustomEngine) ServiceMatch(host string, port int, level int, sender common.ServiceSender, callback common.ServiceCallback) *common.ServiceResult {
return nil // 此引擎不支持Service指纹
}
```
```go
type CustomFingerprint struct {
Name string
Vendor string
Product string
Version string
Rules []MatchRule
}
type MatchRule struct {
Type string // header, body, title等
Pattern string // 匹配模式
Regex *regexp.Regexp
}
func (fp *CustomFingerprint) Match(content []byte) bool {
// 实现具体的匹配逻辑
contentStr := string(content)
for _, rule := range fp.Rules {
switch rule.Type {
case "body":
if rule.Regex.MatchString(contentStr) {
return true
}
case "header":
// 解析HTTP头部进行匹配
// ...
}
}
return false
}
```
--------------------------------
### 查看 test 工具帮助
Source: https://github.com/killmonday/fscanx/blob/master/mylib/finger/cmd/README.md
获取 test 工具的详细使用说明和参数选项。
```bash
cd cmd/test
go run main.go -help
```
--------------------------------
### 验证 Fingers 指纹文件
Source: https://github.com/killmonday/fscanx/blob/master/mylib/finger/cmd/README.md
使用 validate 工具验证 fingers 指纹文件的语法正确性。需要在 cmd/validate 目录下运行。
```bash
cd cmd/validate
go run main.go -engine fingers fingerprints.yaml
```
--------------------------------
### Detect Favicon Fingerprints
Source: https://github.com/killmonday/fscanx/blob/master/mylib/finger/README.md
Initialize the engine and detect fingerprints from a favicon's content. This method is efficient for identifying services based on their icons.
```Go
func TestFavicon(t *testing.T) {
engine, err := NewEngine()
if err != nil {
panic(err)
}
resp, err := http.Get("http://baidu.com/favicon.ico")
if err != nil {
return
}
content := httputils.ReadRaw(resp)
body, _, _ := httputils.SplitHttpRaw(content)
frame := engine.DetectFavicon(body)
fmt.Println(frame.String())
}
```
--------------------------------
### Test Specific Alias Configuration
Source: https://github.com/killmonday/fscanx/blob/master/mylib/finger/doc/sdk.md
This command-line instruction shows how to test a specific alias configuration, in this case, 'nginx_test', using the test tool.
```bash
# 测试特定alias
cd cmd/test
go run main.go -alias aliases.yaml -name nginx_test
```
--------------------------------
### Basic Usage of Fingers Tool
Source: https://github.com/killmonday/fscanx/blob/master/mylib/finger/cmd/engine/README.md
Run the Fingers tool with a target URL. Use the -e flag to specify multiple engines separated by commas. The -v flag enables verbose output for detailed debugging information. The -k flag skips SSL certificate verification.
```bash
go run example.go -u https://example.com
```
```bash
go run example.go -u https://example.com -e fingers,wappalyzer
```
```bash
go run example.go -u https://example.com -v
```
```bash
go run example.go -u https://example.com -k
```
```bash
go run example.go -u https://example.com -f
```
--------------------------------
### Alias 配置测试
Source: https://github.com/killmonday/fscanx/blob/master/mylib/finger/cmd/README.md
使用 test 工具测试 alias 配置的准确性。需要在 cmd/test 目录下运行。
```bash
cd cmd/test
go run main.go -alias aliases.yaml -name nginx_test
```
--------------------------------
### Update Framework Attributes with CPE Information in Go
Source: https://github.com/killmonday/fscanx/blob/master/mylib/finger/doc/sdk.md
Shows how to update a framework's attributes with Common Platform Enumeration (CPE) information. This is crucial for standardizing identification and ensuring compatibility with alias systems.
```go
framework.UpdateAttributes(&common.Attributes{
Part: "a", // application
Vendor: "example",
Product: "product",
Version: "1.0.0",
})
```
--------------------------------
### Output Alias JSON Schema
Source: https://github.com/killmonday/fscanx/blob/master/mylib/finger/doc/sdk.md
This command-line instruction demonstrates how to generate the JSON Schema for the alias engine using the validate tool.
```bash
# 输出alias JSON Schema
go run main.go -schema -engine alias
```
--------------------------------
### Perform Active Fingerprint Detection
Source: https://github.com/killmonday/fscanx/blob/master/mylib/finger/fingers/README.md
This Go code demonstrates how to use FingersEngine for active fingerprint detection. It defines a sender function to construct HTTP requests based on probe data and a callback function to process detection results. Ensure the sender correctly handles the `data` payload to build appropriate requests.
```go
package main
import (
"fmt"
"net/http"
"time"
"github.com/chainreactors/fingers/fingers"
)
func main() {
engine, err := fingers.NewFingersEngine()
if err != nil {
panic(err)
}
// 定义发送器函数,用于主动探测
sender := fingers.Sender(func(data []byte) ([]byte, bool) {
// 根据探测数据构造 HTTP 请求
client := &http.Client{Timeout: 5 * time.Second}
// 这里是简化示例,实际实现需要根据 data 内容构造请求
resp, err := client.Get("http://example.com/probe")
if err != nil {
return nil, false
}
defer resp.Body.Close()
// 返回响应数据
response := make([]byte, 1024)
n, _ := resp.Body.Read(response)
return response[:n], true
})
// 定义回调函数
callback := fingers.Callback(func(framework *common.Framework, vuln *common.Vuln) {
fmt.Printf("主动检测结果: %s\n", framework.String())
if vuln != nil {
fmt.Printf("发现漏洞: %s\n", vuln.Name)
}
})
// 执行主动指纹检测
frameworks, vulns := engine.HTTPActiveMatch(1, sender, callback)
fmt.Printf("检测到 %d 个框架,%d 个漏洞\n", len(frameworks), len(vulns))
}
```
--------------------------------
### Service Fingerprint Matching in Go
Source: https://github.com/killmonday/fscanx/blob/master/mylib/finger/doc/sdk.md
Implements service fingerprint matching for custom engines. This function sends probes to a specified host and port, then matches the response against defined rules to identify frameworks. It supports filtering probes by level and uses a callback for results.
```go
func (e *CustomEngine) ServiceMatch(host string, port int, level int, sender common.ServiceSender, callback common.ServiceCallback) *common.ServiceResult {
// 根据level过滤探测内容
probes := e.getProbesByLevel(level)
for _, probe := range probes {
// 发送探测数据
response, err := sender.Send(host, port, probe.Data, "tcp")
if err != nil {
continue
}
// 匹配响应
if framework := e.matchServiceResponse(response, probe); framework != nil {
result := &common.ServiceResult{
Framework: framework,
}
// 调用回调函数
if callback != nil {
callback(result)
}
return result
}
}
return nil
}
```
--------------------------------
### Test Single Fingerprint with JSON Configuration
Source: https://github.com/killmonday/fscanx/blob/master/mylib/finger/fingers/README.md
This Go code shows how to test a single fingerprint rule defined in JSON format using the `Finger.Match` function. The fingerprint is compiled, and then matched against provided test content for passive detection. Ensure the JSON structure is valid and includes necessary fields like `name` and `rule`.
```go
package main
import (
"encoding/json"
"fmt"
"github.com/chainreactors/fingers/fingers"
)
func main() {
// 定义单个指纹的 JSON 配置
fingerJSON := `{
"name": "nginx",
"rule": [
{
"method": "keyword",
"keyword": ["nginx"]
}
]
}`
// 反序列化创建指纹
var finger fingers.Finger
err := json.Unmarshal([]byte(fingerJSON), &finger)
if err != nil {
panic(err)
}
// 编译指纹规则
err = finger.Compile(false)
if err != nil {
panic(err)
}
// 准备测试内容
testContent := []byte(`HTTP/1.1 200 OK
Server: nginx/1.18.0
Content-Type: text/html
Hello World`)
// 创建内容对象
content := fingers.NewContent(testContent, "", true)
// 测试指纹匹配(被动检测)
framework, vuln, matched := finger.Match(content, 0, nil)
if matched {
fmt.Printf("✓ 指纹匹配成功: %s\n", framework.String())
if framework.Version != "" {
fmt.Printf(" 版本: %s\n", framework.Version)
}
} else {
fmt.Printf("✗ 指纹不匹配\n")
}
}
```
--------------------------------
### Web Fingerprint Detection from HTTP Response
Source: https://github.com/killmonday/fscanx/blob/master/mylib/finger/fingers/README.md
Detects web frameworks and applications by analyzing the raw content of an HTTP response. Requires an HTTP client and utility to read response content.
```go
package main
import (
"crypto/tls"
"fmt"
"net/http"
"github.com/chainreactors/fingers/fingers"
"github.com/chainreactors/utils/httputils"
)
func main() {
// 创建引擎
engine, err := fingers.NewFingersEngine()
if err != nil {
panic(err)
}
// 创建 HTTP 客户端
client := &http.Client{
Transport: &http.Transport{
TLSClientConfig: &tls.Config{InsecureSkipVerify: true},
},
}
// 发送 HTTP 请求
resp, err := client.Get("https://example.com")
if err != nil {
panic(err)
}
defer resp.Body.Close()
// 读取原始响应内容
content := httputils.ReadRaw(resp)
// 进行 Web 指纹匹配
frameworks := engine.WebMatch(content)
// 输出检测结果
for _, framework := range frameworks {
fmt.Printf("检测到: %s (来源: %s)\n", framework.Name, framework.From)
if framework.Version != "" {
fmt.Printf("版本: %s\n", framework.Version)
}
if len(framework.Tags) > 0 {
fmt.Printf("标签: %v\n", framework.Tags)
}
fmt.Printf("CPE: %s\n", framework.CPE())
fmt.Println("---")
}
}
```
--------------------------------
### Optimized FTP Protocol Detection with SOCKS5 Support
Source: https://github.com/killmonday/fscanx/blob/master/README.md
Enhanced FTP protocol detection that includes SOCKS5 proxy support. It attempts anonymous login by default and lists files in directories to help find valuable files.
```go
package main
import (
"fmt"
"github.com/jlaffaye/ftp"
"net"
"time"
"golang.org/x/net/proxy"
)
func main() {
server := "ftp.example.com:21"
proxyAddr := "socks5://127.0.0.1:1080"
// Set up SOCKS5 proxy dialer
proxyDialer, err := proxy.SOCKS5("tcp", "127.0.0.1:1080", nil, proxy.Direct)
if err != nil {
fmt.Printf("Error setting up proxy: %v\n", err)
return
}
// Use the proxy dialer for the FTP connection
conn, err := proxyDialer.Dial("tcp", server)
if err != nil {
fmt.Printf("Error connecting via proxy to %s: %v\n", server, err)
return
}
defer conn.Close()
// Establish FTP connection
client, err := ftp.NewConn(conn, 10*time.Second)
if err != nil {
fmt.Printf("Error creating FTP connection: %v\n", err)
return
}
defer client.Quit()
// Attempt anonymous login
err = client.Login("anonymous", "")
if err != nil {
fmt.Printf("Anonymous login failed: %v\n", err)
return
}
fmt.Println("Anonymous login successful.")
// List files in the current directory (example)
entries, err := client.List(".")
if err != nil {
fmt.Printf("Error listing directory: %v\n", err)
return
}
fmt.Println("Files in current directory:")
for _, entry := range entries {
fmt.Printf("- %s\n", entry.Name)
}
}
```
--------------------------------
### Fingers Tool Command-line Arguments
Source: https://github.com/killmonday/fscanx/blob/master/mylib/finger/cmd/engine/README.md
This section lists available command-line arguments for the Fingers tool, including options for specifying engines, skipping SSL verification, setting the target URL, enabling verbose output, detecting only favicons, and overriding various resource files.
```text
应用选项:
-e, --engines= 指定要使用的引擎,多个引擎用逗号分隔 (默认: fingers,fingerprinthub,wappalyzer,ehole,goby)
-k, --insecure 跳过 SSL 证书验证
-u, --url= 要检测的目标 URL (必需)
-v, --verbose 显示详细调试信息
-f, --favicon 仅检测 favicon
--goby= 覆盖 goby.json.gz
--fingerprinthub= 覆盖 fingerprinthub_v3.json.gz
--ehole= 覆盖 ehole.json.gz
--fingers= 覆盖 fingers_http.json.gz
--wappalyzer= 覆盖 wappalyzer.json.gz
--aliases= 覆盖 aliases.yaml
```