Hack the Boxをやっていると、Webサーバに対してブルートフォースを実施して
コンテンツの調査をする機会が多い。
そしてツールには選択肢がある。
有名なもの、というかよく使われるものとしては以下があげられる。と思う。
・dirbuster (コマンドラインで使う)
・gobuster (GUIで使える)
・nmap --script http-enum
あまりにEnumerationする機会が多かったので、どれが一番早いのか気になってこれらの実行時間を比べてみた。
■条件
・ターゲット
HTBのJoomla端末であるCurling(10.10.10.150)
・Wordlist
kali@kali:~$ wc -l /usr/share/seclists/Discovery/Web-Content/common.txt 4652 /usr/share/seclists/Discovery/Web-Content/common.txt
多すぎず少なすぎずの4652行。
・スレッド
オプション指定で100。
ちなみに気をつけないといけないのは、Webサーバによってはスレッド数多すぎるとBanされることがあるので注意。
・なお、一応比較対象として加えるnmapのnseスクリプトはデフォルトに従う。
■ディレクトリ探索のみ
・dirbuster
→ 17秒
・gobuster
→ 17秒
kali@kali:~$ gobuster dir -u http://10.10.10.150 -w /usr/share/seclists/Discovery/Web-Content/common.txt -t 100
・nmap http-enum
→ 26秒
kali@kali:~$ nmap -p80 10.10.10.150 --script http-enum
■ファイル探索 (対象の拡張子は、html,php,txtの3つ)
・dirbuster
→ 40秒
・gobuster
→ 46秒
kali@kali:~$ gobuster dir -x php,html,txt -u http://10.10.10.150 -w /usr/share/seclists/Discovery/Web-Content/common.txt -t 100
・自作pythonスクリプト
ちなみに自作のpythonスクリプトも作ってみた。
もしかしたら自分で作るスクリプトが一番早かったりする?みたいな
夢みたいなこと考えてしまい、作って実際測るまでわからなかったので一応作ってみた。
なにかとある程度形にするのに3時間近くかかった。
結果、ファイル探索にかかった時間は70秒。
そりゃ既存ツールの方が早いに決まってる。
せっかく作ったので末尾ににコード載せておくけど。改良の余地ありですね。
ちなみに「サイバーセキュリティプログラミング」の本をかなり参考にして作った。
■まとめ
dibuster、gobuster共に4600くらいのワードリストだと17秒くらい。
拡張子3つを対象(=約13800)にすると40秒くらいで終えてくれる。
だいたい同じくらいですが、個人的にはGUIのdirbusterの方が好みです。
右クリックでURLをそのまま開けたり、レスポンスが見れたりできて便利なので。
状況や攻撃端末の環境によって使い分けるといいかもですね。
■自作WebEnumスクリプト
#!/usr/bin/python import requests, Queue, threading, sys, getopt extension = "html,php,txt" fname = "/usr/share/seclists/Discovery/Web-Content/common.txt" threads = 20 url = "" def usage(): print"Usage: python %s [option]"%(sys.argv[0]) print" -u, --url : Target URL" print" -w, --wordlsit : Wordlist (Default: /usr/share/seclists/Discovery/Web-Content/common.txt)" print" -e, --extension : Extension (Default: html,php,txt)" print" -t, --threads : Number of threads (Default: 20)" print"" print 'Ex: python %s -w my_wordlist -e "html,pl,py,sh" -t 100 -u http://target.url/'%(sys.argv[0]) sys.exit(0) def run_exploit(target_url_queue): error_count=0 while not target_url_queue.empty(): target_url = target_url_queue.get() try: req = requests.get(target_url) if not "404" in str(req): print "%s : %s\n"%(req, target_url) except: pass def main(): global url global wordlist global threads global fname global extension if not len(sys.argv[1:]) or not "-u" in sys.argv: usage() try: opts, argv = getopt.getopt(sys.argv[1:],"ht:w:e:u:",["help","threads","wordlist","extension","url"]) except getopt.GetoptError as err: print str(err) usage() for o,a in opts: if o in ("-h", "--help"): usage() elif o in ("-t", "--threads="): threads = int(a) elif o in ("-w", "--wordlist="): fname = a elif o in ("-e", "--extension="): extension = a elif o in ("-u", "--url="): url = a else: assert False, "Unhandled Option" if "http://" in url: base_url = "%s/"%url else: base_url = "http://%s/"%url f = open(fname, "r") file_names = f.readlines() f.close() ex_array = extension.split(",") total_req = len(file_names) * len(ex_array) target_url_queue = Queue.Queue() for file_name in file_names: for ex in ex_array: target_url = base_url + file_name.strip() + "." + ex target_url_queue.put(target_url) print "=============================" print "Target: %s"%(base_url) print "Wordlist: %s"%(fname) print "Extensions: %s"%(extension) print "Thread: %s"%(str(threads)) print "\nTotal Request: %s"%(total_req) print "=============================\n" for i in range(threads): t = threading.Thread(target=run_exploit, args=(target_url_queue,)) t.start() if __name__ == "__main__": main()