21ユーザのパスワードファイルとなっている。user99にはパスワードリストのURLがある。問題タイトルがJohnなだけにJohn the RipperみたいなことをすればFlagがとれそう。
パスワードファイルのフォーマットはよく知らなかったので調べたところ、$6$はSHA512の意味で、さらに次の$まではソルトの部分である。平文のパスワードにソルトを連結したうえハッシュ処理を行った結果が暗号化パスワードとなる。SHA512なのでハッシュ化文字列は512ビット、16進数文字列でこれを表すと、128文字のハッシュとならないといけない。しかし、問題のハッシュをみると86文字しかなく、さらに文字は英数字混じりとなっている。最初、base64でエンコードされていると疑ったが、結果的にそうではなかった。
hashlib.sha512()で総当りすれば簡単にできるとおもったがなかなかうまくいかなかった。Pythonでsha512を生成する方法を調べた結果、cryptモジュールならできそう分かる。しかし、cryptモジュールは
windowsにないのでpythonをubuntuで書いて実行した。時間かかりすぎた。
import hashlib,crypt,getpass,pwd
splited = []
#shadowファイルの各行を$と:で分割した要素を一時的に保存するリスト
salt = []
#各ユーザのソルト
crptpwd = []
#各ユーザの暗号化パスワード
i = 0
#ユーザ数を数える
qtxt = open('q.txt','r')
#shadowファイルを開く
for line in qtxt:
i = i + 1
splited = line.replace('$',':').split(':')
#shadowファイルの各行を$と:の記号で分割
salt.append(splited[3])
#ソルトに相当する部分を抽出
crptpwd.append(splited[4])
#暗号化パスワードに相当する部分を抽出
for j in range(0,i):
passlisttxt = open('passlist.txt','r')
#パスワードリストファイルを開く
for m in passlisttxt:
line2 = m.split('\n')
mycrptpwd = crypt.crypt(line2[0],"$6$"+salt[j]).split('$')
#パスワード候補にソルトを付与してハッシングを行う
if mycrptpwd[3] == crptpwd[j]:
print line2[0]
break
PR