生成AI使ったらHackTheBoxのEditorialで権限昇格してないのにrootフラグとれてしまった件
Hack The Box 「machine」のEditorialについてです!
Walkthrough (Write up)っぽいですが、それではないです(公式HTB的に禁止されているので、Walkthroughではない旨を最初に主張しておきたい)。
https://app.hackthebox.com/machines/Editorial
最近HTBにハマっています。セキュリティ系出身ではないので、あまり経験が無いのですが、相手マシンに侵入してから権限昇格する前にrootフラグをとれてしまったので驚きました。意図したものなのか、それともマシンの設計ミス?なのか謎のままです。
ちなみにタイトルが誇張していますが、chatGPT使ったのは最初入り口だけです。CTF系やHacking系はまだ勉強し始めて日が浅いので、chatGPTや他人のWriteUPを見たりしないと解くのは難しいです。今回はchatGPTの力を借りて穴の入り口を見つけれました。あ〜穴があったら入りたい(笑)
Let's start!
というわけで、/uploadにたどり着いたのですが、
アップロードしたときにどのような変化があるか?を見てみると
→previewが表示される。。。
怪しい。。。
さすがの初心者の僕でもここに脆弱性がありそうなのは感じます。でも初心者なので、何をしていいのか分かりません。適当にいろんな拡張子のファイルをアップロードをすれば良いのかな、程度です。
ファイルのスクリーニングはjsのみで動いているのか?それともバックエンドを一旦介しているのか。つまり、どの拡張子がアップロードできるか、を考えましたが、どの拡張子もアップロードできそうでした。
ますます怪しい。。。
でも次のステップが分からないので、よし、聞いてみよう!
ということで、最初に「1. View the Source Code」しましょう!
と言われました。
ふむふむ。よしランダムにファイルをアップロードする前にcodeを見るんですね!すると以下を見つけました!
<script>
document.getElementById('button-cover').addEventListener('click', function(e) {
e.preventDefault();
var formData = new FormData(document.getElementById('form-cover'));
var xhr = new XMLHttpRequest();
xhr.open('POST', '/upload-cover');
xhr.onload = function() {
if (xhr.status === 200) {
var imgUrl = xhr.responseText;
console.log(imgUrl);
document.getElementById('bookcover').src = imgUrl;
document.getElementById('bookfile').value = '';
document.getElementById('bookurl').value = '';
}
};
xhr.send(formData);
});
</script>
previewボタンをクリックするとどうやら/upload-coverにPOSTリクエストされるようです。しかもファイルがサーバ側に保存されることが分かりました。htmlにjsコードが書いてあり、consoleログ(console.log(imgUrl))にそのファイル名が記載されれています。保存したファイルのパスが取得できるということが分かります!おお!
ということで続いては、
ChatGPTに言われた「3. File upload attack」に移ります!
とりあえず適当にファイルをアップロードしてみます。
consoleに、保存先のパスが出力されました。
しかし保存されたファイルのパスは分かりましたが、そこに手動でアクセスしてもNot Foundになります。はて、なんででしょう。。。?
Wiresharkで確認したところ画像をHTML上で表示させるために保存された画像のURLへGETリクエストが発生して、200 OKが返って来ています(以下は違う画像をuploadしたときのですが)。これを見ると確実にファイルは保存されたことが分かります。
はて、何がトリガーとなってファイルが削除されるのでしょうか。。。?(解決した今も結局分からない。時間?アクセス回数?refereerヘッダーとかの問題か何か?)
またChatGPTに聞きます。すると以下のヒントをもらえました。
ふむふむ。「入力フィールドの分析か!」
ここであることに気がつきました。ファイルのアップロードばかりに気をとられてて、その隣にあるURL入力欄の存在を忘れてました。
完全にSSRF脆弱性がありますと、言っているような気がします。。。
以下はBurpの画面ですが、URL の欄に自分のマシンのIPアドレスを入れて送信してみました。
するとアクセスされました!。SSRFで確定です。
ちなみにこのときはリバースシェルするのかと思って、頑張ってました(以下はchatGPTのアドバイス)。
出来る気配が無かったので、やり方を再度見直していたら、あることに気がつきました。
あれ、localhostのパターンか!?
そこで、nginxとwebアプリがどのポートでつながっているのかを調べます!学習用でかつ初学者向けなので1台のpcで構成されていることが想像できるのでlocalhostを使えるだろうと思いました。あとはWEBアプリとして真っ先に推測できるのが、(マシンがeasyの難易度であることを踏まえると)PHPとFlaskです。PHPはそこまで詳しくないのであれですが、Flaskは5000番ポートが使用されることが多いです。
for port in range(5000, 5002):
payload = {"bookurl": "http://localhost:{}".format(port)}
r = requests.post(post_url, headers=headers, data=payload, files=files)
print(r.status_code)
print(r.text)
file_url = base_url + r.text
r = requests.get(file_url)
print(r.text)
time.sleep(1)
Boom!ビンゴ!!!
endpointの情報が返ってきたので、後はそこにアクセスすればユーザ情報が返ってきました。SSHで試したら上手いことアクセス出来ました!
権限昇格はどうも難しい印象があります。
sudo -l で何も見つからなければ?マークがついて詰みます。
ファイル探っていたら、以下がありました。
gitか!そう思って色々探してみましたが、root奪取出来る気がしなかったです。そして再度、ファイルの探索に戻りました。するとroot.txtがおいてありました。
ラッキーなのですが、困惑していました。root権限奪取していないし、横展開すらしていない。なのにroot.txtをread出来てしまいました。これで本当に良かったのだろうか。。。?作問者の意図することなのか、それともミスなのか。。。
誰か教えてください。
これって正攻法だったのだろうか。。。?
学習する機会を何か逃した気がします。
以上!
この記事が気に入ったらサポートをしてみませんか?