漏洞猎人赏金笔记-如何编写Bug Bounty自动化脚本
漏洞猎人赏金笔记-如何编写Bug Bounty自动化脚本
声明:文章中涉及的程序(方法)可能带有攻击性,仅供安全研究与教学之用,读者将其信息做其他用途,由用户承担全部法律及连带责任,文章作者不承担任何法律及连带责任。
前言
本文原文作者为@pry0cc,本文主要是对原文相关内容的提炼以及笔记,出于易读性考虑,笔者对很多地方做了一定量的注释或者删改(因为原文中的脚本存在一定问题)。
本文主要讲解的是经典的自动化信息搜集以及数据处理和漏洞扫描的流程.
正文
主体逻辑
脚本的主要逻辑如下:
设置变量,检查范围目录(scope directory)是否存在,而后读取 创建目录,例如:每次扫描创建扫描目录 扫描主体逻辑(重点) 计算扫描所需的时间 通知用户扫描已经完成
下面来看一下(注意:原文中的脚本有点问题,思路是没毛病的,笔者这里做了些修改):
scan.sh
#!/bin/bash
# 设置变量
id="$1"
ppath="$(pwd)"
scope_path="$ppath/scope/$id"
timestamp="$(date +%s)"
scan_path="$ppath/scans/$id-$timestamp"
# 检查scope_path是否存在
if [ ! -d "$scope_path" ]; then
echo "Path doesn't exist"
echo 1
fi
mkdir -p "$scan_path" &&
cd "$scan_path"
# 开始 scan
echo "starting scan:"
mkdir -p "$scope_path" &&
touch "$scope_path/roots.txt" &&
echo "$1" >> "$scope_path/roots.txt"
cat "$scope_path/roots.txt"
cp -v "$scope_path/roots.txt" "$scan_path/roots.txt"
sleep 3
## 添加扫描逻辑
# 扫描 时间
end_time=$(date +%s)
seconds="$(expr $end_time - $timestamp)"
time=""
if [[ "$seconds" -gt 59 ]];
then
minutes=$(expr $seconds / 60)
time="$minutes minutes"
else
time="$seconds seconds"
fi
echo "Scan $id took $time"
资产发现
根域名
确定范围内的公司,获取尽可能多的根域名,这里可以用whoxy.com
(吐槽一下,这类网站大多需要付费,和撒旦,fofa一样)
Censys/Shodan
利用Censys或Shodan发现现有DNS没有记录的IP地址,对这些IP进行反向DNS查询,看看你是否能确定IP、ASN、根域名或其他未链接的但是是公司拥有的资产
子域名枚举
收集完根域名之后,进行子域枚举
DNS 暴力破解
预备知识:
DNS AAAA
记录:将一个域名或子域名映射到IPv6
DNS A
记录:将一个域名或子域名映射到IPv4
注意点:使用A记录,可以为同一个域名使用几个
DNS AAAA
记录来实现冗余。几个名字可以翻译成互联网上的同一个地址。在这种情况下,每个人都需要有自己的AAAA
记录,指向同一个IP地址。
这里首选的工具是 puredns 和 shuffledns
这里需要注意的是:安装massdns之后才能使用shuffledns,而要使 massdns
正常运行,必须有两个字典:
用于DNS暴力破解的字典 解析器(resolvers)字典
下面继续扩展扫描脚本:
##执行扫描
echo "starting scan:"
cat "$scope_path/roots.txt"
cp -v "$scope_path/roots.txt" "$scan_path/roots.txt"
cat "$scan_path/roots.txt" | subfinder | anew subs.txt
cat "$scan_path/roots.txt" | shuffledns -w "$ppath/lists/pry-dns.txt" -r "$ppath/lists/resolvers.txt" | anew subs.txt
测试一下:
./scan.sh amazon.com
得到一个subs.txt文件,里面包含了28711个子域名;
这里需要注意泛解析问题(wildcard DNS records)
何为泛解析?
利用通配符 * (星号)来做次级域名以实现所有的次级域名均指向同一IP地址
举个例子:
例如域名是abc.com
做一个*.abc.com的次级域名A记录指向111.111.111.111,那么生效后当访问者无论是输入“123.abc.com”还是“123.123.abc.com”甚至可以是“!@#..12345.ww.a.abc.com”这样的 任意字符均可以指向到111.111.111.111这个IP地址。
泛域名解析的用途:
1.可以让域名支持无限的子域名(这也是泛域名解析最大的用途);2.防止用户错误输入导致的网站不能访问的问题;
3.可以让直接输入网址登陆网站的用户输入简洁的网址即可访问网站;
泛域名在实际使用中作用是非常广泛的,比如实现无限二级域名功能,提供免费的url转发,在IDC部门实现自动分配免费网址,在大型企业中实现网址分类管理等等,都发挥了巨大的作
泛解析问题可能会导致误报或导致我们发现实际上不存在的子域,从而可能浪费我们的时间。为了解决这个问题,我们可以使用Puredns
puredns resolve subs.txt -r path/lists/resolvers.txt -w resolved.txt
发现了一个根域名被泛解析(*.signon.aws.amazon.com
),最后将上面发现的28711个子域名减少到12039个!
继续添加一些被动源,扫描脚本变为如下:
##执行扫描
echo "starting scan:"
cat "$scope_path/roots.txt"
cp -v "$scope_path/roots.txt" "$scan_path/roots.txt"
## DNS 枚举-子域名暴力破解
cat "$scan_path/roots.txt" | haktrails subdomains | anew subs.txt | wc -l
cat "$scan_path/roots.txt" | subfinder | anew subs.txt | wc -l
cat "$scan_path/roots.txt" | shuffledns -w "$ppath/lists/pry-dns.txt" -r "$ppath/lists/resolvers.txt" | anew subs.txt | wc -l
## DNS泛解析对抗
puredns resolve "$scan_path/subs.txt" -r "$ppath/lists/resolvers.txt" -w "$scan_path/resolved.txt" | wc -l
dnsx -l "$scan_path/resolved.txt" -json -o "$scan_path/dns.json" | jq -r '.a?[]?' | anew "$scan_path/ips.txt" | wc -l
到目前为止一共生成了以下文件:
dns.json ips.txt resolved.txt roots.txt subs.txt
HTTP服务枚举
下面利用nmap来扫描前面发现的ip(主要是ips.txt
)
nmap -T4 -vv -il "$scan_path/ips.txt" --top-ports 3000 -n --open -oX "$scan_path/nmap.xml"
而后利用httpx这个工具来发现HTTP服务器(在此之前用tew这个工具对输出的xml进行文件格式转换)
tew -x nmap.xml
tew -x nmap.xml | httpx
继续:
tew -x nmap.xml -dnsx dns.json —vhost | httpx -json -o http.json
上面这一行命令的意思
对DNSx JSON输出进行关联,将DNSx输出中的主机名解析为Nmap XML输出文件中的IP地址和开放端口
最后将输出的格式改变一下:
cat http.json | jq -r ‘.url’ | sed -e ‘s/:80$//g’ -e ‘s/:443$//g’ | anew http.txt
使用 sed 删除 80 和 443 端口,因为这可能会影响某些工具
现在来看一看扫描脚本:
##执行扫描
echo "starting scan:"
cat "$scope_path/roots.txt"
cp -v "$scope_path/roots.txt" "$scan_path/roots.txt"
## DNS 枚举-子域名暴力破解
cat "$scan_path/roots.txt" | haktrails subdomains | anew subs.txt | wc -l
cat "$scan_path/roots.txt" | subfinder | anew subs.txt | wc -l
cat "$scan_path/roots.txt" | shuffledns -w "$ppath/lists/pry-dns.txt" -r "$ppath/lists/resolvers.txt" | anew subs.txt | wc -l
## DNS泛解析对抗
puredns resolve "$scan_path/subs.txt" -r "$ppath/lists/resolvers.txt" -w "$scan_path/resolved.txt" | wc -l
dnsx -l "$scan_path/resolved.txt" -json -o "$scan_path/dns.json" | jq -r '.a?[]?' | anew "$scan_path/ips.txt" | wc -l
## 端口扫描与http服务发现
nmap -T4 -vv -il "$scan_path/ips.txt" --top-ports 3000 -n --open -oX "$scan_path/nmap.xml"
tew -x "$scan_path/nmap.xml" -dnsx "$scan_path/dns.json" --vhost -o "$scan_path/hostport.txt" | httpx -json -o "$scan_path/http.json"
cat "$scan_path/http.json" | jq -r '.url' | sed -e 's/:80$//g' -e 's/:443$//g' | sort -u > "$scan_path/http.txt"
HTTP爬虫
这部分主要爬取url,而后用ffuf处理,这里使用Gospider进行爬虫(hakrawler或xnLinkFinder),projectdiscovery最近新开源了katana,读者可以试试
gospider -S http.txt —json | grep “{” | jq -r ‘.output’
捕获HTTP响应
对上面的脚本进行简单修改:
tew -x "$scan_path/nmap.xml" -dnsx "$scan_path/dns.json" --vhost -o "$scan_path/hostport.txt" | httpx -sr -srd responses
responses为新创建的目录
看一下这些文件的内部,可以看到包括响应头在内的所有内容。
更新脚本之后:
##执行扫描
echo "starting scan:"
cat "$scope_path/roots.txt"
cp -v "$scope_path/roots.txt" "$scan_path/roots.txt"
## DNS 枚举-子域名暴力破解
cat "$scan_path/roots.txt" | haktrails subdomains | anew subs.txt | wc -l
cat "$scan_path/roots.txt" | subfinder | anew subs.txt | wc -l
cat "$scan_path/roots.txt" | shuffledns -w "$ppath/lists/pry-dns.txt" -r "$ppath/lists/resolvers.txt" | anew subs.txt | wc -l
## DNS泛解析对抗
puredns resolve "$scan_path/subs.txt" -r "$ppath/lists/resolvers.txt" -w "$scan_path/resolved.txt" | wc -l
dnsx -l "$scan_path/resolved.txt" -json -o "$scan_path/dns.json" | jq -r '.a?[]?' | anew "$scan_path/ips.txt" | wc -l
## 端口扫描与http服务发现
nmap -T4 -vv -il "$scan_path/ips.txt" --top-ports 3000 -n --open -oX "$scan_path/nmap.xml"
tew -x "$scan_path/nmap.xml" -dnsx "$scan_path/dns.json" --vhost -o "$scan_path/hostport.txt" | httpx -sr -srd "$scan_path/responses" -json -o "$scan_path/http.json"
cat "$scan_path/http.json" | jq -r '.url' | sed -e 's/:80$//g' -e 's/:443$//g' | sort -u > "$scan_path/http.txt"
## 爬虫
gospider -S "$scan_path/http.txt" --json | grep “{” | jq -r '.output?' | tee "$scan_path/crawl.txt"
提取JS文件
这一部分主要提取js文件:
cat crawl.txt | grep “\.js” | httpx -sr -srd js
脚本更新如下:
##执行扫描
echo "starting scan:"
cat "$scope_path/roots.txt"
cp -v "$scope_path/roots.txt" "$scan_path/roots.txt"
## DNS 枚举-子域名暴力破解
cat "$scan_path/roots.txt" | haktrails subdomains | anew subs.txt | wc -l
cat "$scan_path/roots.txt" | subfinder | anew subs.txt | wc -l
cat "$scan_path/roots.txt" | shuffledns -w "$ppath/lists/pry-dns.txt" -r "$ppath/lists/resolvers.txt" | anew subs.txt | wc -l
## DNS泛解析对抗
puredns resolve "$scan_path/subs.txt" -r "$ppath/lists/resolvers.txt" -w "$scan_path/resolved.txt" | wc -l
dnsx -l "$scan_path/resolved.txt" -json -o "$scan_path/dns.json" | jq -r '.a?[]?' | anew "$scan_path/ips.txt" | wc -l
## 端口扫描与http服务发现
nmap -T4 -vv -il "$scan_path/ips.txt" --top-ports 3000 -n --open -oX "$scan_path/nmap.xml"
tew -x "$scan_path/nmap.xml" -dnsx "$scan_path/dns.json" --vhost -o "$scan_path/hostport.txt" | httpx -sr -srd "$scan_path/responses" -json -o "$scan_path/http.json"
cat "$scan_path/http.json" | jq -r '.url' | sed -e 's/:80$//g' -e 's/:443$//g' | sort -u > "$scan_path/http.txt"
## 爬虫
gospider -S "$scan_path/http.txt" --json | grep “{” | jq -r '.output?' | tee "$scan_path/crawl.txt"
## JS提取
cat "$scan_path/crawl.txt" | grep “\.js” | httpx -sr -srd js >> js.text
如何处理搜集到的数据
下面很多借鉴了Tomnomnom的方法;
这里使用一个叫vimprev的工具(其实就是一小段脚本),同时使用vim,可以在一个目录中的文件之间快速切换.
在~/.vimrc
中添加如下:(注意原文中是有问题的,笔者这里进行了修正)
if $VIMENV == 'prev'
noremap <Space> :n<CR>
noremap <Backspace> :N<CR>
noremap <C-D> :call delete(expand('%')) <bar> argdelete % <bar> bdelete<CR>
set noswapfile
endif
vimprev设置(目录你可以自己设置,笔者这里设置的是$HOME
)
$cat ~/vimprev
#!/bin/bash
VIMENV=prev vim $@
vimprev
环境变量设置:
export PATH=$PATH:$HOME
一旦设置好,当在响应目录中时,只需输入如下:
#使用vim预览当前目录中的所有文件
vimprev $(find -type f)
上面这个命令可以让你在目录中的每个文件之间移动
gf
在响应中寻找AWS keys
cat responses | gf aws-keys >> aws-keys.txt
tok
从当前给定的文件(存储HTTP响应的文件)中提取关键词并删除特殊字符和空格。
这些关键词可以添加到单词列表中(字典)以进行进一步枚举,或者用于标识上下文(可用于构建定制化字典)。
find . -type f | tok | sort | uniq -c | sort -rn | head -n 40
qsreplace + ffuf
使用qsreplace和ffuf,可以寻找漏洞,如路径遍历或SQL注入漏洞。
cat crawl.txt | grep "?" | qsreplace ../../../../etc/passwd | ffuf -u 'FUZZ' -w - -mr '^root:'
总结
本文主要讲解了自动化信息搜集的经典流程:
设置变量,检查范围目录(scope directory)是否存在,而后读取 创建目录,例如:每次扫描创建扫描目录 执行扫描逻辑: DNS枚举,子域名暴力破解 DNS泛解析对抗 端口扫描与http服务发现 爬虫 JS文件提取 计算扫描所需的时间 通知用户扫描已经完成
后面对处理数据以及漏洞扫描进行了简单总结,处理数据以及漏洞扫描这部分后面有文章会详细阐述,全文结束.
参考
https://github.com/d3mondev/puredns
https://github.com/blechschmidt/massdns
https://github.com/projectdiscovery/shuffledns
https://powerdmarc.com/zh/what-is-a-dns-aaaa-record/
https://i.pry0.cc/lists/
https://github.com/projectdiscovery/dnsx
https://github.com/pry0cc/tew
https://www.youtube.com/watch?v=l8iXMgk2nnY
https://github.com/tomnomnom/qsreplace