Subdomain 子域名有时候有规律,比如有个app.domain.com
,就有可能存在app-dev.domain.com
或者appdev.domain.com
或者 dev-app.domain.com
,app-api.domain.com
,app-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
如果是搜索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"