模糊测试
ffuf
ffuf 是一个常用的模糊测试工具,使用方法简单,功能应该也算强大,但是我总觉得效率不算高,而且在线程数开太高时很容易报错,这里的报错是指测试结果 error 而不是工具本身报错崩溃。
使用起来很简单,在我们指定了 wordlist 的内容作为 FUZZ 时(不一定非得是 FUZZ,可以是其他字符串),就可以像引用变量一样在后面的 URL 里进行暴力测试。
目录模糊测试
1 | $ ffuf -w /usr/share/seclists/Discovery/Web-Content/directory-list-2.3-small.txt:FUZZ -u http://SERVER_IP:PORT/FUZZ |
-w:指定 wordlist,:FUZZ表示把 wordlist 里的值带入后面FUZZ的位置,有点类似于变量赋值的感觉-u:指定 URL,其中的FUZZ就是带入前面 wordlist 里的值
扩展模糊测试
1 | $ ffuf -w /usr/share/seclists/Discovery/Web-Content/web-extensions.txt:FUZZ -u http://SERVER_IP:PORT/blog/indexFUZZ |
- 寻找
blog/目录下文件名为index.*的文件 FUZZ是直接替换,如果 wordlist 里有.,那 FUZZ 前面就不需要额外加.了
页面模糊测试
1 | $ ffuf -w /usr/share/seclists/Discovery/Web-Content/directory-list-2.3-small.txt:FUZZ -u http://SERVER_IP:PORT/blog/FUZZ.php |
- 在扩展模糊测试中我们找到了潜在文件的扩展名,这里就用
FUZZ.php找.php格式的文件
递归模糊测试
1 | $ ffuf -w /usr/share/seclists/Discovery/Web-Content/directory-list-2.3-small.txt:FUZZ -u http://SERVER_IP:PORT/FUZZ -recursion -recursion-depth 1 -e .php -v |
-recursion:启用递归扫描-recursion-depth:指定递归深度,深度为 1 时只会模糊主目录及其直接子目录,如果识别出任何子子目录,如/login/usr就不会继续递归了-e:指定扩展名,例如-e .php-v:输出完整的 URL
感觉输出比较乱并且比较繁杂,可以输出到文件里然后再筛选有效信息,这样效率会高一些。
虚拟主机模糊测试
1 | $ ffuf -w /usr/share/seclists/Discovery/DNS/subdomains-top1million-5000.txt:FUZZ -u http://SERVER_IP:PORT/ -H 'Host: FUZZ.DOMAIN_NAME' |
参数模糊测试
GET
1 | $ ffuf -w /usr/share/seclists/Discovery/Web-Content/burp-parameter-names.txt:FUZZ -u http://SERVER_IP:PORT/admin/admin.php?FUZZ=key |
POST
1 | $ ffuf -w /usr/share/seclists/Discovery/Web-Content/burp-parameter-names.txt:FUZZ -u http://SERVER_IP:PORT/admin/admin.php -X POST -d 'FUZZ=key' -H 'Content-Type: application/x-www-form-urlencoded' |
跟 curl 差不多,测试完之后可以用 curl 获取相应的响应。
过滤
可以通过 -h 查看 FLITER OPTIONS,通过对应的参数设置可以过滤我们的输出,比如 HTTP 状态码或者响应大小。
这里的过滤是过滤掉我们设置的参数,可以通过 , 来过滤多个参数,例如 -fs 900 就会过滤掉 Size: 900 的响应,-fs 900,986 就会过滤掉 Size: 900 或 Size: 986 的响应,而不是划定一个范围,我刚才就设定错参数所以过滤错了,当无用的响应大小都一样的时候,就可以用 -fs 进行一个过滤。
这里是过滤掉设定的参数而不是保留,我刚才就以为是保留,但是发现每次都有 Size: 0 留下来,我才反应过来。
PS:刚才我把一个 ‘b’ 打成 ‘p’ 了,瞪了半天改了半天都没发现,所以 URL 能复制还是别手打了。
练习
先添加 IP 地址和主机名到 /etc/hosts 里:
1 | $ echo "TARGET_IP academy.htb" | sudo tee -a /etc/hosts |
再在当前环境里设置变量 PORT=TARGET_PORT。
Task1
Run a sub-domain/vhost fuzzing scan on ‘*.academy.htb’ for the IP shown above. What are all the sub-domains you can identify? (Only write the sub-domain name)
非常简单,直接用 ffuf 测就好了,我先扫了子域名,没扫到,然后扫虚拟主机,扫到了。
1 | ffuf -w /usr/share/seclists/Discovery/DNS/subdomains-top1million-5000.txt:FUZZ -u http://academy.htb:$PORT/ -H 'Host: FUZZ.academy.htb' -fs 985 |
答案是 archive test faculty。
Task2
Before you run your page fuzzing scan, you should first run an extension fuzzing scan. What are the different extensions accepted by the domains?
分别测试刚才扫到的三个子域名,别忘了先加到 /etc/hosts 里。
1 | $ ffuf -w /usr/share/seclists/Discovery/Web-Content/web-extensions.txt:FUZZ -u http://archive.academy.htb:$PORT/indexFUZZ |
取一个并集,答案是 .php .phps .php7。
Task3
One of the pages you will identify should say ‘You don’t have access!’. What is the full page URL?
说实话我一看到的时候是没打有头绪的,总之肯定是要进行页面模糊测试对吧,我就先扫:
1 | $ ffuf -w /usr/share/seclists/Discovery/Web-Content/directory-list-2.3-small.txt:FUZZ -u http://archive.academy.htb:$PORT/FUZZ |
扫完之后发现 archive.academy.htb 和 faculty.academy.htb 各有一个 courses 目录,因为我们之前见到过虚拟主机一直套娃的情况,那我们就对这两个站点进行一个递归扫描:
1 | $ ffuf -w /usr/share/seclists/Discovery/Web-Content/directory-list-2.3-small.txt:FUZZ -u http://archive.academy.htb:$PORT/FUZZ -recursion -recursion-depth 1 |
这扫完发现没什么变化,没有更深的页面,然后我就懵逼了,想着扫一下 .php 文件,但是因为每次模糊测试的效率都好低,不知道是不是因为 wsl 的原因(我记得我用虚拟机也慢,应该是我不够了解 ffuf),所以我打算先去看看 hint:
Run a recursive scan on all sub-domains you found, and use all of the extensions you found. Use ‘PORT’ instead of the port shown above, like http://xxxxx.academy.htb:PORT/xxxxxxx ..etc
说实话,没太看懂,让我递归扫描,并且添加刚才发现的所有扩展名,最后一句关于 PORT 的没看懂。
每个子域每个扩展名都手动测试太麻烦了,我们就充分利用 ffuf 的特性,自动化一波。
先创建一个 sublist.txt,内容为:
1 | archive |
然后我们运行如下命令:
1 | $ ffuf -w ./sublist.txt:FUZZSUB,/usr/share/seclists/Discovery/Web-Content/directory-list-2.3-small.txt:FUZZ -u http://FUZZSUB.academy.htb:$PORT/FUZZ -recursion -recursion-depth 1 -e '.php,.phps,.php7' -v -fc 403 |
这个命令本身是没有问题的,我们可以用它去完成任务,但是:
1 | :: Progress: [10406/1051968] :: Job [1/3] :: 86 req/sec :: Duration: [0:03:18] :: Errors: 156 :: |
扫了一会,这个时间消耗有点恐怖了,超出靶机的时间限制了。所以我就又去另寻他路了。
因为只有 faculty 这个子域有 .php7,所以我们可以只对它扫 .php7,分成两次扫,这样可以减少不小的工作量,虽然依旧不小。
那就先单独扫 faculty:
1 | $ ffuf -w /usr/share/seclists/Discovery/Web-Content/directory-list-2.3-small.txt:FUZZ -u http://faculty.academy.htb:$PORT/FUZZ -recursion -recursion-depth 1 -e '.php,.phps' -v -fc 403 >> faculty.txt |
扫了得有一个多小时,扫完之后我们看一下 faculty.txt,在最后面有一个 Size 不是 0 的地址:
1 | [Status: 200, Size: 774, Words: 223, Lines: 53, Duration: 238ms] |
这就说明它的响应不是空的,我们用 curl 获取一下:
1 | $ curl http://faculty.academy.htb:$PORT/courses/linux-security.php7/ |
成功发现 You don't have access!,提交该地址,去掉末尾的 /,果然正确。
到这我才反应过来 hint 的最后一句是啥意思,是让我把端口换成 PORT,因为我提交了一次没过哈哈哈。
虽然已经过了,但是确保万无一失,我又用正则表达式筛了一下:
1 | $ cat faculty.txt | grep 'Size: [^0]' |
跟这两个对应的其实就是我们一开始扫到的子目录和后面扫到的具体文件:
1 | [Status: 301, Size: 337, Words: 20, Lines: 10, Duration: 236ms] |
所以以后扫描的时候加一个 -fs 0 是不是会好一些?也不好说。
其实这个时候 archive 和 test 那边还没扫完,但是我们看一下目前的结果:
1 | $ cat archive_test.txt| grep 'Size: [^0]' |
还是只有之前扫到的那个子目录。
Task4
In the page from the previous question, you should be able to find multiple parameters that are accepted by the page. What are they?
要我们去进行参数扫描,直接扫:
1 | $ ffuf -w /usr/share/seclists/Discovery/Web-Content/burp-parameter-names.txt:FUZZ -u http://faculty.academy.htb:39415/courses/linux-security.php7?FUZZ=key |
扫完之后发现端口填错了,这回是复制粘贴错了,在犯错方面我还是有水平的。
我们还是重新扫一下:
1 | $ ffuf -w /usr/share/seclists/Discovery/Web-Content/burp-parameter-names.txt:FUZZ -u http://faculty.academy.htb:$PORT/courses/linux-security.php7?FUZZ=key -fs 774 |
GET 和 POST 都扫一下,没啥问题。
Task5
Try fuzzing the parameters you identified for working values. One of them should return a flag. What is the content of the flag?
让我们测试刚才扫到的参数,我按照之前在这一章节学的生成了一个纯数字的 wordlist 去扫 user,啥也没扫到,就去看了下 hint:
Try to find a good wordlist from ‘seclists’. Once you find a working value, use ‘curl’ to send a POST request with the value to get the flag.
hint 说去 seclists 里找,我就一步步的找跟 user 相关的,找到了一个 /usr/share/seclists/Usernames/Names/names.txt,那我们就直接开测了:
1 | $ ffuf -w /usr/share/seclists/Usernames/Names/names.txt:FUZZ -u http://faculty.academy.htb:$PORT/courses/linux-security.php7 -X POST -d 'username=FUZZ' -H 'Content-Type: application/x-www-form-urlencoded' -fs 781 |
其实第一次我没扫出来,原因是扫的过程中靶机到时间自动关闭了。
那既然扫出来了我们就用 curl 获取一下响应:
1 | $ curl http://faculty.academy.htb:$PORT/courses/linux-security.php7 -X POST -d 'username=harry' -H 'Content-Type: application/x-www-form-urlencoded' |
完结。