akkietech’s diary

セキュリティ関連メインの自分用メモ書き。twitter: @akkietech

Webブルートフォースツール比較

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()